UVA - 12716
这是一道要转两次弯的数论题
题意 a^b=c=gcd(a,b),求在N以内有多少对这样的数
一开始我觉得可以枚举a c 求b,但是这样范围太大,担心会T,后来看了别人的题解,发现可以把c放在外圈,a放在内圈,这样可以减少a遍历的个数
类似于素数筛,这样每次枚举都会 有一次判断 gcd(a,b)=c?的操作,总共复杂度为n(logn)^2,通过多次枚举,发现一个规律,b=a-c;
所以复杂副减少为n(logn)
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<iostream> #include<algorithm> #include<string.h> #include<stdlib.h> #include<iostream> #include<algorithm> #include<string> #include<queue> #include<math.h> #include<map> #define MST(vis,x) memset(vis,x,sizeof(vis)) #define INF 0x3f3f3f3f #define ll long long #define ull unsigned long long #define maxn 30000005 using namespace std; int s1[maxn]; int main() { int t,n,sum,i=1; for(int c=1; c<=maxn/2; c++) { for(int a=c+c; a<=maxn; a+=c) { int b=a-c; if((a^b)==c) s1[a]++; } } for(int a=2;a<maxn;a++) s1[a]+=s1[a-1]; cin >> t; while(t--) { scanf("%d",&n); sum=0; printf("Case %d: %d\n",i++,s1[n]); } return 0; }