小y的质数
题目链接:https://ac.nowcoder.com/acm/contest/634/C
链接:https://ac.nowcoder.com/acm/contest/634/C
来源:牛客网
题目描述
给出一个区间[L,R],求出[L,R]中孪生质数有多少对。由于这是一个区间筛质数的模板题。所以小k不屑于去写。
所以出题人只好yy了另一道题。
定义k生互质数为满足y + k与y - k互质的数。
现在给出区间[L,R],你需要输出区间内k生互质数有多少对
我们说一对k生互质数在区间[L,R]内,当且仅当y+k∈[L,R]y+k∈[L,R]且y−k∈[L,R]y−k∈[L,R]
输入描述:
一行三个数字L,R,k
输出描述:
一行一个数字表示区间[L,R]内的k生互质数的对数
备注:
0≤L,R≤10180≤L,R≤1018
1≤k≤1013
思路:
首先看到这个题,数据量这么大,肯定不是暴力,分析表达式:y + k与y - k互质,也就是gcd(y-k,y+k)=1 那么令x=y-k 所以有gcd(x,x+2*k)=1 这就好处理多了 显然x和x不是互质的 那么x和2*k肯定是互质的
所以gcd(x,2*k)互质。 所以这题就转化为求x的取值范围内有多少个数与2*k互质。 有求区间多少个数与某个数互质的算法 看博客:https://www.cnblogs.com/caijiaming/p/10745074.html
但是还是有坑点,具体看代码:
#include<iostream> #include<vector> using namespace std; typedef long long LL; void solve(LL n,LL l,LL r) { vector<LL> p; for(LL i=2;i*i<=n;i++)//求n的所有质因子 { if(n%i==0) { p.push_back(i); while(n%i==0) { n/=i; } } } if(n>1) p.push_back(n); //容斥 // cout<<"*&"<<endl; LL ans=0; LL len=p.size(); // cout<<len<<" "<<endl; for(LL i=1;i<((LL)1<<len);i++)//二进制枚举 { // cout<<"*"<<endl; LL mul=1,cnt=0; for(LL j=0;j<len;j++) { // cout<<"*"<<endl; if(i&(1<<j)) { cnt++; mul*=p[j]; } } LL sum=(l-1)/mul; LL sum1=r/mul; if(cnt&1) ans+=sum1-sum; else ans-=sum1-sum; } if(l==0) ans++;//坑点!! cout<<(r-l+1)-ans<<endl; } int main() { LL l,r,k; cin>>l>>r>>k; // if(l>r) swap(l,r); if((r-2*k)>=l) solve(k*2,l,r-2*k); else cout<<"0"<<endl; return 0; }
当初的梦想实现了吗,事到如今只好放弃吗~