哈爾濱理工邀請賽 E題 MOD

2022-09-24 01:45:12 字數 1649 閱讀 3392

題目:

description

kim剛剛學會c語言中的取模運算(mod)。他想要研究一下乙個數字a模上一系列數後的結果是多少。幫他寫個程式驗證一下。

input

第一行乙個整數t代表資料組數。

接下來t組資料,第一行乙個整數n,接下來n個數字ai

接下來一行乙個整數m,接下來m個數字bi。

output

對於每個bi,輸出bi%a1%a2%...%an。

sample input

10 9 5 7

14 8 27 11 25

sample output

hint

在c語言中,amodb是a%b

樣例解釋:

14%10%9%5%7=4

8%10%9%5%7=3

資料範圍:

1<=n<=100000

1<=m<=100000

1<=ai<=1000000000

0<=bi<=1000000000

分析:如果很多個數字對乙個數字進行取模,第二個取模會把第乙個取得模改變的數字,一定會比第一次取模得到的結果小,因此有效的取模的數字首先應該是遞減的。這樣,我們就可以在輸入ai的時候,把無效的數字刪除,留下一串遞減的陣列。

然後,最重要的一步,在陣列中找到上次取模得到的結果比它小於或者等於的第乙個數,然後用這個數字對上次得到的結果進行取模操作。

如果對每次向後面遍歷一遍呢,遍歷的時間複雜度是o(n),一共會輸入m個數字,所以總的時間複雜度是o(mn),顯然,在這種情況下無法滿足時間要求。因此,為了能提高效率,只能在查詢時進行優化,我們可以採用二分法,二分地來查詢每次要找到的數字的位置,這樣,查詢的時間複雜度為o(log(n)),總的時間複雜度是o(m log(n)),可以在最壞的情況下在時間要求之內得到結果。

下面是標準程式(本人親測)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

long long num[100005];

int fin(int low,int high,int val){

if(high-low<=1)

return low;

int mid=(low+high)/2;

if(num[mid]<=val)

fin(low,mid,val);

else

fin(mid,high,val);

int main(){

int t;

int n;

int m;

int i,j,k;

int b;

long long last;

int coun;

long long temp;

scanf("%d",&t);

while(t--){

scanf("%d",&n);

scanf("%lld",&last);

num[0]=last;

coun=1;

for(i=1;i

哈爾濱理工大學全國邀請賽A題(dp)

a.棋盤村 time limit 1000 ms memory limit 32768 k total submit 868 212 users total accepted 122 116 users special judge no description 一名騎著馬的強盜闖進了原本平靜祥和的棋...

鞍山邀請賽 部分題

題意 給你n個行星,移動k個行星,繞他們的質心速度變得更大,使得這些行星的速度變得更大,那麼就要使得 i的值更小即可,include include include includeusing namespace std double zb 70100 double sum 70005 double ...

2018南昌邀請賽網路賽d題

剛開始看到此提時也沒想到dp 但是仔細一思考可以發現確實是 我們只要單獨處理第一位數 剩下的符號和數字看成乙個物品 進行類似揹包的dp即可 首先預處理所有火柴和符號 根據輸入的總火柴進行一次dp即可 include include include includeusing namespace std...