2022 China Collegiate Programming Contest (CCPC) Weihai Site 补题:G.Grade 2

题目链接:Problem - G - Codeforces

解题思路:

1.先暴力打表看看有没有规律,当k=15,17时发现循环节分别为16和32。(k为2的n次方时,一个都没有。)

 发现循环节的规律为k的二进制数的n次。

2.对一个循环的所以结果进行前缀和的操作,得出一个循环能有多少个gcd为1的。

3.找到左边界和右边界中有多少个循环节,再对l和r进行模的处理,得出答案。

时间复杂度O1。

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e6+5;
int n,k,l,r;
int a[N];
int cmp(int x){
	int ans=1;
	while(x){
		x/=2;
		ans*=2;
	}
	return ans;
}
void check(int x){
	for(int i=1;i<=x;i++){
		if(__gcd(((i*k)^(k)),k)==1){
			a[i]=a[i-1]+1;
		}else{
			a[i]=a[i-1];
		}
	}
} 
signed main(){
	cin>>k>>n;
	int x=cmp(k);
	check(x);
	while(n--){
		cin>>l>>r;
		int ans=0; 
		l--;
		ans+=(r/x)*a[x];
		ans+=a[r%x];
		ans-=(l/x)*a[x];
		ans-=a[l%x];
		cout<<ans<<endl;
	}
	
	
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/m0_63569670/article/details/127756817