hdu6085 Rikka with Candies
来源:互联网 发布:阿里云深圳节点怎么样 编辑:程序博客网 时间:2024/06/01 19:32
- /**
- 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]即可
- **/
- #include<bits/stdc++.h>
- typedef long long ll;
- const int MAXN = 5e4 + 70;
- using namespace std;
- int a[MAXN], b[MAXN];
- int res[MAXN], vis[MAXN];
- vector<int> G[MAXN];
- ll dig[MAXN][35];
- set<int> st;
- ll ans[MAXN];
- void init() {
- for(int i = 1; i < MAXN - 3; i++) {
- for(int j = 1; j * j <= i; j++) {
- if(i % j) continue;
- G[i].push_back(j);
- if(i / j != j) G[i].push_back(i / j);
- }
- sort(G[i].begin(), G[i].end());
- }
- }
- int main() {
- init();
- int n, m, q, k, T;
- scanf("%d", &T);
- while(T--) {
- st.clear();
- memset(vis, 0, sizeof vis);
- memset(res, 0, sizeof res);
- memset(ans, 0, sizeof ans);
- scanf("%d%d%d", &n, &m, &q);
- int max_data = -1;
- for(int i = 0; i < n; i++) {
- scanf("%d", &a[i]);
- vis[a[i]] = 1;
- max_data = max(max_data, a[i]);
- }
- for(int i = 0; i < m; i++) {
- scanf("%d", &b[i]);
- st.insert(b[i]);
- }
- sort(b, b + m);
- for(int i = 1; i <= 5e4; i++) {
- ll su = 0;
- for(int j = 0; j < 32; j++) {
- su = su * 2 + vis[i + j];
- dig[i][j + 1] = su;
- dig[i][j + 1] <<= (31 - j);
- }
- }
- for(int i = 1; i <= max_data; i++) {
- for(int j = 0; j < G[i].size(); j++) {
- int x = G[i][j];
- if(!st.count(x)) continue;
- int L = 0, R = x - 1;
- while(L <= R) {
- int d = L / 32;
- if(i + L > 5e4) break;
- if(R - L >= 31) {
- ans[d] ^= dig[i + L][32];
- L += 32;
- } else {
- ans[d] ^= dig[i + L][R - L + 1];
- L = R + 1;
- }
- }
- }
- }
- int num = 0;
- for(int i = 0; i * 32 <= 5e4; i++) {
- int j = (i + 1) * 32 - 1;
- int t = 32;
- while(t--) { res[j] = ans[i] & 1; j--; ans[i] >>= 1; }
- }
- for(int i = 0; i < n; i++) {
- int x = a[i];
- res[x] += m - (upper_bound(b, b + m, x) - b);
- }
- while(q--) {
- scanf("%d", &k);
- printf("%d\n", res[k] & 1);
- }
- }
- return 0;
- }
阅读全文
1 0
- hdu6085 Rikka with Candies
- HDU6085-Rikka with Candies
- hdu6085 Rikka with Candies [bitset+想法]
- 【2017多校】HDU6085 Rikka with Candies
- Rikka with Candies(HDU6085) (bitset加速计数)
- Hdu6085 Rikka with Candies(2017多校第5场)
- 2017多校训练Contest5: 1001 Rikka with Candies hdu6085
- Rikka with Candies
- Rikka with Candies HDU
- HDU 6085 Rikka with Candies
- HDU 6085 Rikka with Candies
- Rikka with Candies(bitset操作)
- HDU 6085 Rikka with Candies
- hdu 6085 Rikka with Candies
- Hdu 6085 Rikka with Candies【思维+Bitset】
- hdu 6085 Rikka with Candies bitset
- HDU 6085 Rikka with Candies 模拟bitset
- HDU 6085 Rikka with Candies (bitset)
- JavaWeb学习总结(十六)——JSP中的九个内置对象
- C#解析Json(包含Model中实体类型字段)
- 大质数检测&&分解质因子 poj1811 Prime Test
- Android开发中遇到的各类问题汇总
- django 入门-安装Django
- hdu6085 Rikka with Candies
- 通过DNS AAAA记录和IPv6地址传输后门有效载荷
- Elven Postman HDU
- Redis伪集群
- 割接—— 业务转移
- tensorflow问题集合
- 经典笔试题 ——判断两个字符串是否为变形词
- Java虚拟机的JVM垃圾回收机制
- 根据当前日期得到前/后n天日期 根据指定日期得到前/后n天日期