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, 这样就可以得到每一个余数的计数答案了
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <algorithm>
- #include <cstring>
- #include <map>
- #include <set>
- #include <vector>
- #include <queue>
- #include <cmath>
- #include <bitset>
- using namespace std;
- bitset<50005>a, b, bb, ans;
- void solve(int maxk)
- {
- bb.reset();
- ans.reset();
- for(int i = maxk; i >= 0; --i)
- {
- ans[i] = (bb & (a >> i)).count() & 1;
- if(b[i])
- {
- for(int j = 0; j <= 50000; j += i)
- bb.flip(j);
- }
- }
- return;
- }
- int main()
- {
- int CASE;
- scanf("%d", &CASE);
- while(CASE--)
- {
- a.reset();
- b.reset();
- int n, m, q;
- scanf("%d%d%d", &n, &m, &q);
- int x;
- int maxx = 0;
- while(n--)
- {
- scanf("%d", &x);
- a.set(x);
- }
- while(m--)
- {
- scanf("%d", &x);
- b.set(x);
- maxx = max(maxx, x);
- }
- solve(maxx);
- while(q--)
- {
- scanf("%d", &x);
- printf("%c\n", ans[x] ? '1' : '0');
- }
- }
- return 0;
- }
阅读全文
0 0
- hdu 6085
- hdu 6085 bitset优化
- bitset(hdu 6085)
- HDU 6085 暴力bitset
- hdu 6085(bitset)
- hdu 6085(bitset优化)
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- linux 服务器部署 lnamp 四、mysql
- unity中如何实现画面滚动
- javaScript学习笔记
- 【Lua学习笔记】Lua中协程的使用
- innerHTML基础知识
- hdu 6085
- 【编程语言学习】C++ Primer 对constexpr 和常量表达式的讲解
- HashMap的实现原理
- C 一一 static和extern关键字详解
- 使用python fit,predict出现的错误
- 读取excel文件信息实例2
- 并发基本概念介绍
- python基础——函数编程
- javascript随机数