hdu 6085

来源:互联网 发布:ec软件 编辑:程序博客网 时间:2024/06/16 14:25

多校第五场的1001Rikka with Candies是一道大数据量的计数题。

题意:给定A,B两个序列,有q个询问,每个询问给出一个k,问对于每一k,有多少种情况满足ai % bj = k?A,B的元素个数数据量均为50000,询问次数也为50000


分析:题目时限是3500ms,也就是算法只能是常数很小的n*n的算法才能勉强过掉,所以只能用bitset来加速计数,同时为了加速,必须避免大量使用取模运算,只能用以除数为单位采用加和的方式不断累加,这样可以不使用取模运算,同时这也是我第一次接触bitset,在比赛时并没有AC,之后看了很多博客了解了bitset的用法和大牛们关于这道题的解法,这里推荐一个我看到的博客【2017多校】HDU6085 Rikka with Candies 这个博客和我比赛时想到的思路差不多,但是比赛时我用bitset没有实现。

思路就是枚举余数k, 因为余数为k的条件是ai >= k, bj > k, 所以要从大到小枚举k,同时将上次枚举产生的倍速记录下来,这样bitsetz中记录的就是大于k的bj的倍数,然后和bitset-a做&运算就可以得到bj和a中共有的数字,这样bb & (a >> i)可以得到(a - i) % b = 0的数了,注意bitset右移i位就相当于所有的元素全部减少了i, 这样就可以得到每一个余数的计数答案了

[cpp] view plain copy
print?
  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <cstdlib>  
  4. #include <algorithm>  
  5. #include <cstring>  
  6. #include <map>  
  7. #include <set>  
  8. #include <vector>  
  9. #include <queue>  
  10. #include <cmath>  
  11. #include <bitset>  
  12.   
  13. using namespace std;  
  14.   
  15. bitset<50005>a, b, bb, ans;  
  16.   
  17. void solve(int maxk)  
  18. {  
  19.     bb.reset();  
  20.     ans.reset();  
  21.     for(int i = maxk; i >= 0; --i)  
  22.     {  
  23.         ans[i] = (bb & (a >> i)).count() & 1;  
  24.         if(b[i])  
  25.         {  
  26.             for(int j = 0; j <= 50000; j += i)  
  27.                 bb.flip(j);  
  28.         }  
  29.     }  
  30.     return;  
  31. }  
  32.   
  33. int main()  
  34. {  
  35.     int CASE;  
  36.     scanf("%d", &CASE);  
  37.     while(CASE--)  
  38.     {  
  39.         a.reset();  
  40.         b.reset();  
  41.         int n, m, q;  
  42.         scanf("%d%d%d", &n, &m, &q);  
  43.         int x;  
  44.         int maxx = 0;  
  45.         while(n--)  
  46.         {  
  47.             scanf("%d", &x);  
  48.             a.set(x);  
  49.         }  
  50.         while(m--)  
  51.         {  
  52.             scanf("%d", &x);  
  53.             b.set(x);  
  54.             maxx = max(maxx, x);  
  55.         }  
  56.         solve(maxx);  
  57.         while(q--)  
  58.         {  
  59.             scanf("%d", &x);  
  60.             printf("%c\n", ans[x] ? '1' : '0');  
  61.         }  
  62.     }  
  63.     return 0;  
  64. }