想不出来真失败,
总结一下这个题目主要是在这几点上:
1.很容易想到枚举a,b,然后判断__gcd(a,b)是否等于a^b。也很容易发现这样做是完全不行的。(1/1)
2.分析出gcd和xor其实并没有太大关系(1/1)
3.然后分析出gcd和xor并没有关系,而且时间不够,那么就要充分利用xor或者gcd的性质。(2/2)
4.鉴于1和3,那么我们可以换个枚举的方式,枚举a和a的因子,或者枚举c和c的倍数。然后去找b。(1/1)
5.由于想不出合适的解法,那么我们可以打表找规律(1/2)
1)首先找n和ans[n]的规律,只能得出ans[n-1]和ans[n]相差很小,ans[x]单增,然而得不到准确公式(1/1)
2) 虽然得不到准确公式,但是不能就此停止,还是可以找到一些重要性质的:
如果不是单纯的计算ans[n],而是看一下满足条件的a,b,c的性质,那么可以得出a-b=c。(0/1)
6.数论基础十分薄弱,导致书上给出a-b=c的证明是看了半天,这个也会影响解题 (0/3)。
1) 比如说 a-b>=gcd ,为什么呢?因为gcd|a,gcd|b,so gcd|a-b,而且a一定!=b,so gcd>=a-b (0/1)
2)又比如 a-b<=a xor b (这里a>=b) ,想想很显然 (0/1)
3) 由1)、2) gcd<=a-b<=a xor b ,所以如果满足条件必有c=gcd=a-b=a xor b。(0/1)
7.对筛法的时间复杂度比较模糊 (0/1)
书上说这个复杂度大约为O(nlogn),我却认为远远不止。
for(int c=1;c<=maxn;c++)
{
for(int a=2*c;a<=maxn;a+=c)
{
int b=a-c;
if(c== (a^b) )
{
dp[a]++;
}
}
}
8.由此得出结论,枚举a、c(保证b一定是c的倍数),b=a-c 判断a xor b ==c (0/1)
#include<bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
const int maxn= 30000000 ;
int n;
int ans[maxn+10];
int dp[maxn+5];
int init()
{
for(int c=1;c<=maxn;c++)
{
for(int a=2*c;a<=maxn;a+=c)
{
int b=a-c;
if(c== (a^b) )
{
dp[a]++;
}
}
}
ans[0]=0;
for(int i=1;i<=maxn;i++)
{
ans[i]=ans[i-1]+dp[i];
}
}
int main()
{
init();
int T,kase=0;scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
printf("Case %d: %d\n",++kase,ans[n] );
}
return 0;
}
找规律:
#include<bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
//const int maxn= ;
int get(int x)
{
int ans=0;
for(int i=1;i<=x;i++)
{
for(int j=1;j<=i;j++)
{
if(__gcd(i,j)== (i^j) )
{
cout<<i<<" "<<j<<" "<<(i^j)<<endl;
ans++;
}
}
}
return ans;
}
int main()
{
get(100);
/*
for(int i=1;i<=100;i++)
{
printf("%d : %d\n",i,get(i));
}
*/
return 0;
}