題意:a陣列n個數,b陣列m個數,q個查詢, 每次給出乙個k,詢問有多少對(i,j), 使得ai % bj = k, 輸出對數對模2的值
資料範圍:
1<=m,n,q<=50,000
1<=ai,bi<=50,000
0<=ki<=maxbi
分析:
首先,用乙個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]即可
ac**:
#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;
}
**:hnust_derker
位 mysql 查詢 Mysql 查詢 按位運算
前言 雖說這是件小事兒,但本寶寶思前想後,還是為它留下一筆,嘿嘿。反正寫部落格不浪費紙和筆!好久沒有開啟我的逗比模式了,我親愛的乖徒弟dba,dbb,dbaa等,好久不見你們,遙祝幸福快樂 db。整個事情其實使這樣的,最近的專案中,有乙個表,最終是這樣的 一共 位,每一位的取值是 和 額,後來還有 ...
hdu1429位運算狀態壓縮
第一次接觸位運算的狀態壓縮,這題本來我是用優先佇列寫的,用vector儲存鑰匙。本來以為會超時,沒想到是記憶體超限。無奈,找大神,發現正確姿勢是狀態壓縮。這題用來學 位運算的狀態壓縮是相當不錯,很好理解。題意是乙個人在乙個迷宮裡逃生,迷宮有鎖,有鑰匙,相應的鑰匙開相應的鎖。共有10種鎖。利用位運算就...
數學 模 位運算 HDU 6058
hnust derker 模 位運算,現在還是不打能明白,先留個記錄。hdu 6085 rikka with candies 題意 a陣列n個數,b陣列m個數,q個查詢,每次給出乙個k,詢問有多少對 i,j 使得ai bj k,輸出對數對模2的值 思路 首先,用乙個vis陣列01方式記錄a陣列中的數...