UVa 12716 GCD XOR

链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=594&problem=4669&mosmsg=Submission+received+with+ID+2196163

题意:给定n(1<=n<=3e7),求有多少对整数(a,b)满足1<=b<=a<=n,gcd(a,b)=a^b。

分析:设gcd(a,b)=c,a^b=c等价于a^c=b,因此可以枚举a和c,然后检查gcd(a,a^c)==c,复杂度为O(n(longn)^2),果断T。。实际上满足条件的数对必然满足b=a-c,因为b=a^c>=a-c,c=gcd(a,b)=gcd(a-b,b)<=a-b。因此只需要检验c==a^(a-c)。

复杂度为O(nlogn),大约是7e8,但是有多组数据,因此要预处理前3e7个,记第i个为dp[i],a=i时的数对有_a[i]对 ,则dp[i]=dp[i-1]+_a[i],可以线性处理,总的复杂度为O(nlogn)。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<vector>
 5 using namespace std;
 6 const int maxn=3e7+5;
 7 bool have[maxn];
 8 long long _a[maxn],dp[maxn];
 9 long long ans=0;
10 void solve(){
11     ans=0;
12     for(int c=1;c<=maxn;c++){
13         for(int a=2*c;a<=maxn;a+=c){
14             if((a^(a-c))==c)_a[a]++;
15         }
16     }
17 }
18 int main(){
19     //freopen("e:\\in.txt","r",stdin);
20     memset(_a,0,sizeof(_a));
21     solve();
22     dp[1]=0;
23     for(int i=2;i<maxn;i++){
24         dp[i]=dp[i-1]+_a[i];
25     }
26     int t,n;
27     cin>>t;
28     for(int kase=1;kase<=t;kase++){
29         scanf("%d",&n);
30         printf("Case %d: %d\n",kase,dp[n]);
31     }
32     return 0;
33 }

 

posted @ 2017-06-26 20:49  7391_KID  阅读(201)  评论(0编辑  收藏  举报