數學 模 位運算 HDU 6058

2021-08-05 23:30:16 字數 1878 閱讀 4844

**:hnust_derker

模+位運算,現在還是不打能明白,先留個記錄。

/**

hdu 6085 rikka with candies

題意:a陣列n個數,b陣列m個數,q個查詢, 每次給出乙個k,詢問有多少對(i,j), 使得ai % bj = k, 輸出對數對模2的值

思路:首先,用乙個vis陣列01方式記錄a陣列中的數是否出現過,因為有ai % bj = k,所以也就是(ai - k) % bj = 0,不妨設ai - k = x,那麼bj則是x的因子,因為

是ai % bj = k,所以k一定比bj小,即k的取值範圍是[0, bj)那麼可以列舉每個x, 再列舉每個x的因子c,如果c不在b陣列出現, 就不管它;否則的話,就在[0, bj)

中的每乙個y的值, 對應的加上vis陣列中x + y的值,舉個例子:

vis陣列中對於6 7 8 9 10 11的出現情況是0 1 1 0 1 0

對於x列舉到6,它的因子列舉到3(假設3在b陣列存在)的時候,如果有(ai - k) % 3 = 0,那麼就是說,如果k可以取值,k在[0, 3)也就是[0, 2]的範圍內,也就轉換為

ai = x + k, 也就是6 + [0, 2],那麼現在只需要看對應取值為k的時候,x + k(ai)是否存在,如果存在那麼k的值即可加上1, 因為此時(ai, 3)形成了一對模為k的數

設res陣列是記錄餘數為k的對數, x=6,c=3的情況如下所示

vis 6 7 8 9 10 11

0 1 1 0 1 0

x+k 6 7 8

res[0, 1, 2] + vis[x + 0, x + 1, x + 2]

= res[0, 1, 2] + vis[6, 7, 8]

= res[0, 1, 2] + [0, 1, 1]

就是說res[0]+0, res[1]+1, res[2]+1, 代表有(6+1)%3=0,(6+2)%3=0,

即(7, 3)形成了一對餘數為1的數,(8, 3)形成了一對餘數為2的數

還有因為直接相加複雜度是o(n^2),題目說只需要模2, 那麼可以用異或來寫,用異或的話也不可能乙個乙個來,所以就用將連續若干個01值壓縮成乙個整數來異或,

這樣就是o(n^2 / 32), 還有一點就是對於x=0,因為所有正整數都是0的因子,對0分開寫,原式就是(0 + k) % bj = k => k % bj = k, 就是找在a陣列中k存在的前提

下,在b陣列中找出比k大的數的數量加進res[k]即可

**/#includetypedef long long ll;

const int maxn = 5e4 + 70;

using namespace std;

int a[maxn], b[maxn];

int res[maxn], vis[maxn];

vectorg[maxn];

ll dig[maxn][35];

setst;

ll ans[maxn];

void init()

sort(g[i].begin(), g[i].end());

}}int main()

for(int i = 0; i < m; i++)

sort(b, b + m);

for(int i = 1; i <= 5e4; i++)

}for(int i = 1; i <= max_data; i++) else }}

}int num = 0;

for(int i = 0; i * 32 <= 5e4; i++)

}for(int i = 0; i < n; i++)

while(q--)

}return 0;

}

巧妙的位運算及模運算

原帖 輸入2的n次方 如果突然要你輸入2的19次方,你是不是還要想一下呢?敲個524288多累啊。用位運算 1 19又快又準。乘除2的倍數 千萬不要用乘除法,非常拖效率。只要知道左移1位就是乘以2,右移1位就是除以2就行了。比如要算25 4,用25 2就好啦。判斷偶數 a 2取模是最常用的判斷方法之...

求模運算( )和按位與運算( )

最近看了看hashmap原始碼,覺得裡面的乙個按位與運算用的很優雅,記錄一下。jdk7中,hashmap是 陣列 鍊錶 的結構,為了讓hashmap裡的元素分布的更加均勻,就要在陣列中給每個元素乙個合適的位置,求模運算是乙個不錯的方法,但是,jdk7中使用了一種更加優雅的方法,原始碼中的方法如下 s...

取模運算 和按位與

最近在研究 redis 原始碼,發現一些平時不怎麼用的編碼習慣,感覺挺有趣,記錄下 function isodd1 num function isodd2 num 以上兩個方法都是用來判斷乙個數是否為奇數,但是用到的操作符不同,有什麼區別 取模操作符是基於 十進位制 人類思維 的一種取模方式,如 1...