Educational Codeforces Round 37-G.List Of Integers题解
一、题目
二、题目链接
http://codeforces.com/contest/920/problem/G
三、题意
给定一个$t$,表示有t次查询。每次查询给定一个$x$, $p$, $k$,需要输出一个大于$x$、与$p$互质、第$k$大的数字。如样例1所示,比$7$大、与$22$互质、第$1$大的数字是$9$,第$2$大的数字是$13$,第$3$大的数字是$15$。
四、思路
二分+容斥原理。
二分一个数字$mid$,看看$[x+1,mid]$之间与$p$互质的数的个数。需要注意的是,如果个数是$k$,还要判断二分的$mid$是不是与$p$互质。如果是,说明要输出的值在$[x+1, mid)$之间,要需要继续做二分。(注意括号样式哦)
统计$[x+1, mid]$之间与$p$互质的数的个数,方法是:把这个区间内$p$的素因子的倍数全部筛掉,剩余的就是与$p$互质的了。在筛的过程中,比如$p$是$12$,素因子是$2$、$3$,筛掉$2$的倍数的方法是:区间长度$len - (mid / 2 - x / 2)$。同理,筛掉$3$的倍数的方法也一样。但是,对于所有$6$的倍数,会被减两次,所以,需要再加一次。而这个过程,其实就是容斥原理。
在这个题目中,利用容斥原理统计个数时,有两个写法:
1、每次二分一个上界值$mid$,就枚举二进制;
2、保存所有的询问,对每个询问的$p$,都预处理出它的所有素因子组合的乘积。然后,再枚举每一个询问,传入二分上界值$mid$时,枚举预处理的$p$的所有素因子组 合的乘积即可。(详细的写法可参考源代码)
另外,还有一点,在做询问之前,需要预处理出$[1, 1e6]$区间内所有数字的素因子。
五、源代码
1、写法一:每次二分一个上界值$mid$,就枚举二进制;
- #pragma GCC optimize(2)
- #pragma comment(linker, "/STACK:102400000, 102400000")
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long LL;
- ;
- template <class T> inline void read(T &x) {
- int t;
- bool flag = false;
- ')) ;
- if(t == '-') flag = true, t = getchar();
- x = t - ';
- + t - ';
- if(flag) x = -x;
- }
- bool prime[MAXN];
- vector<LL> d[MAXN];//d[i]:数字i的所有素因子
- void init() {
- ;
- ; i <= N; ++i)d[i].clear(), prime[i] = true;
- ; i <= N; ++i) {
- if(prime[i]) {
- for(int j = i + i; j <= N; j += i)prime[j] = false;
- }
- }
- ; i <= N; ++i) {
- if(prime[i]) {
- for(int j = i; j <= N; j += i)d[j].push_back(LL(i));
- }
- }
- }
- /**[x+1, mid]**/
- LL calc(LL x, LL p, LL mid) {
- LL res = mid - x;
- /*枚举二进制:
- 如果i=5,二进制为0101,从低位数起,第0位和第2位为1,
- 那么就取d[p]的第0个和第2个素因子,计算乘积,去做容斥操作。
- 同时,需要统计取得素因子的个数。
- 如果是奇数,那么,容斥操作中符号是+,否则是-。
- */
- , t = << d[p].size(); i < t; ++i) {
- LL cnt = , prod = ;
- ; j > ; j >>= , ++k) {
- ) {
- cnt++;
- prod *= d[p][k];
- }
- }
- res -= (mid / prod - x / prod) * (cnt % == ? : -);
- }
- return res;
- }
- int main() {
- #ifndef ONLINE_JUDGE
- freopen("Ginput.txt", "r", stdin);
- #endif // ONLINE_JUDGE
- LL T, x, p, k, low, high, mid, ans = , tmp;
- init();
- read(T);
- while(T--) {
- read(x), read(p), read(k);
- low = x, high = 1LL << ;/*这个地方要特别注意,写大了就超时。*/
- ) {
- mid = (low + high) / ;
- tmp = calc(x, p, mid);
- if(tmp < k)low = mid;
- else if(tmp > k)high = mid;
- else {
- if(__gcd(mid, p) > 1LL)high = mid;
- else {
- ans = mid;
- break;
- }
- }
- }
- printf("%lld\n", ans);
- }
- ;
- }
2、保存所有的询问,对每个询问的$p$,都预处理出它的所有素因子组合的乘积。然后,再枚举每一个询问,传入二分上界值$mid$时,枚举预处理的$p$的所有素因子组 合的乘积;
- #pragma GCC optimize(2)
- #pragma comment(linker, "/STACK:102400000, 102400000")
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long LL;
- typedef tuple<LL, LL, LL> T3L;
- typedef pair<LL, LL> P2L;
- ;
- template <class T> inline void read(T &x) {
- int t;
- bool flag = false;
- ')) ;
- if(t == '-') flag = true, t = getchar();
- x = t - ';
- + t - ';
- if(flag) x = -x;
- }
- bool prime[MAXN];
- vector<LL> d[MAXN];/*d[i]:数字i的素因子*/
- vector<P2L> f[MAXN];/*f[i]:数字i的素因子组合的乘积和该组合的素因子个数*/
- vector<T3L> qs;
- void init() {
- ;
- qs.clear();
- ; i <= N; ++i)d[i].clear(), f[i].clear(), prime[i] = true;
- ; i <= N; ++i) {
- if(prime[i]) {
- for(int j = i + i; j <= N; j += i)prime[j] = false;
- }
- }
- ; i <= N; ++i) {
- if(prime[i]) {
- for(int j = i; j <= N; j += i)d[j].push_back(LL(i));
- }
- }
- }
- /**[x+1, mid]**/
- LL calc(LL x, LL p, LL mid) {
- LL res = mid - x;
- ; i < f[p].size(); ++i) {/*直接枚举素因子组合的乘积*/
- LL prod = f[p][i].first, cnt = f[p][i].second;
- res -= (mid / prod - x / prod) * (cnt % == ? : -);
- }
- return res;
- }
- int main() {
- #ifndef ONLINE_JUDGE
- freopen("Ginput.txt", "r", stdin);
- #endif // ONLINE_JUDGE
- LL T, x, p, k, low, high, mid, ans = , tmp;
- init();
- read(T);
- ; i < T; ++i) {
- read(x), read(p), read(k);
- qs.push_back(make_tuple(x, p, k));/*保存所有询问*/
- }
- /*预处理每个询问的p的素因子组合的乘积、组合个数。
- 写法同方法1。
- */
- ; t < T; ++t) {
- tmp = >(qs[t]);
- ) {
- , top = << d[tmp].size(); i < top; ++i) {
- LL cnt = , prod = ;
- ; j > ; j >>= , ++k) {
- ) {
- cnt++;
- prod *= d[tmp][k];
- }
- }
- f[tmp].push_back(make_pair(prod, cnt));
- }
- }
- }
- ; t < T; ++t) {
- x = >(qs[t]), p = >(qs[t]), k = >(qs[t]);
- low = x, high = 1LL << ;/*这个地方要特别注意,写大了就超时。*/
- ) {
- mid = (low + high) / ;
- tmp = calc(x, p, mid);
- if(tmp < k)low = mid;
- else if(tmp > k)high = mid;
- else {
- if(__gcd(mid, p) > 1LL)high = mid;
- else {
- ans = mid;
- break;
- }
- }
- }
- printf("%lld\n", ans);
- }
- ;
- }
Educational Codeforces Round 37-G.List Of Integers题解的更多相关文章
- Educational Codeforces Round 37 G. List Of Integers (二分,容斥定律,数论)
G. List Of Integers time limit per test 5 seconds memory limit per test 256 megabytes input standard ...
- Educational Codeforces Round 37
Educational Codeforces Round 37 这场有点炸,题目比较水,但只做了3题QAQ.还是实力不够啊! 写下题解算了--(写的比较粗糙,细节或者bug可以私聊2333) A. W ...
- Educational Codeforces Round 37 (Rated for Div. 2)C. Swap Adjacent Elements (思维,前缀和)
Educational Codeforces Round 37 (Rated for Div. 2)C. Swap Adjacent Elements time limit per test 1 se ...
- Educational Codeforces Round 63 (Rated for Div. 2) 题解
Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...
- Educational Codeforces Round 65 (Rated for Div. 2)题解
Educational Codeforces Round 65 (Rated for Div. 2)题解 题目链接 A. Telephone Number 水题,代码如下: Code #include ...
- Educational Codeforces Round 64 (Rated for Div. 2)题解
Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...
- Educational Codeforces Round 58 (Rated for Div. 2) 题解
Educational Codeforces Round 58 (Rated for Div. 2) 题目总链接:https://codeforces.com/contest/1101 A. Min ...
- Educational Codeforces Round 60 (Rated for Div. 2) 题解
Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...
- Educational Codeforces Round 37 (Rated for Div. 2) G
G. List Of Integers time limit per test 5 seconds memory limit per test 256 megabytes input standard ...
- codeforces 920 EFG 题解合集 ( Educational Codeforces Round 37 )
E. Connected Components? time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
随机推荐
- msgsrvmgr.cpp:5:37: fatal error: kdl_conversions/kdl_msg.h: No such file or directory #include <kdl_conversions/kdl_msg.h>
/home/xxx/ros_workspace/src/bp_protocol_bridge/protospot/src/msgsrvmgr.cpp::: fatal error: kdl_conve ...
- PHP自定义XML类实现数组到XML文件的转换
这两天在公司写和各应用商店应用内搜索的接口,大致就像百度应用内搜索这样的东西,具体可以点下面的链接查看. 百度应用内搜索 有的应用商店需要JSON格式的数据,所以我只需要用下面的语句就可以返回对方服务 ...
- 递归--练习11--noi9273 PKU2506Tiling
递归--练习11--noi9273 PKU2506Tiling 一.心得 25 a[i]%=10;(高精度时) 26 这里错了,花了好久改好 27 28 29 int* f(int n){ 30 if ...
- wpf--- TextBlock文字设置属性
ProgressBar控件的重要属性: FontFamily——控件中显示文本的字体 FontSize——控件中显示的字体的大小 Foreground——控件 ...
- python json与字典对象互相转换
改文章转自:https://www.cnblogs.com/Lin-Yi/p/7640147.html 1 import requests 2 import json 3 ''' 4 json.loa ...
- Tornado的cookie过期问题
首先,web应用程序是使用HTTP协议进行数据传输,因为HTTP协议是无状态的,所以一旦提交数据完成后,客户端和服务器端的连接就会被关闭,再次进行数据的交换就得重新建立新的连接,那么,有个问题就是服务 ...
- 个人知识管理系统Version1.0开发记录(10)
物理分页 这次我们运用Mybatis拦截器来实现物理分页,后面会运用动态sql来实现,或者运用Map/CollectionUtils/StringUtils编写工具类来实现.oracle是运用的row ...
- Meteor.js异步全解
翻译来源: http://phucnguyen.info/blog/everything-you-need-to-know-about-async-meteor/ posted in Web Deve ...
- 导入arr包
提起项目的aar包 导入目标项目中 添加依赖
- 433.92 TX RX module design and test recording。。
This paper records the process of 433.92 TX RX module design and test,fyi. 1 RX module The circuit ...