【題目大意】題目給你一個N,讓你求 兩個數字 A,B,且 A>=B<=N,是的 gcd(A,B) == A^B。
a^b = c等價於a^c = b 所以枚舉a和c,而a和c全部枚舉肯定TLE,所以高效算法:通過c是a的約數這個關係來枚舉會減小循環,必須要將c放在循環外面,因爲c的情況比較少。其實本題就是要求:c=a-b(規律),c=a^b
【代碼】
#include <cstdio>
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
#define maxn 30000000
int s[30000000+10];
int init(){
int sum = 0;
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)
s[a]++; // a 所滿足的所有可能 因爲 a < n 在求n的時候要把前n項全部加起來
}
}
for(int i = 2; i <= maxn; i++) //前i個一共有多少,真是巧妙
s[i] += s[i-1];
}
int main (){
int counts = 0,num;
scanf("%d",&num);
init();
while(num--){
int n;
scanf("%d",&n);
printf("Case %d: %d\n",++counts,s[n]);
}
return 0;
}