Satisfies gcd (A, a, a, a) = a XOR b; Among them 1<=b <=a<=n.
There are several theorems that need to be known first to do this problem:
XOR: A and B = C so a xor C = b;
Then we make gcd (A, b) = C; So a is a C multiple. We can take a multiple of C as a by traversing C and then sifting through the method. How can we ask for B?
The book provides a way to use a XOR c=b with gcd (A, b) =c authentication. But this method is timed out, GCD is the total time complexity of the logn level, n (logn) ^2. This is not acceptable to us.
There is also a way to prove b=a-c. The proof is still not easy:
First GCD (A, B) =c<=a-b second to prove a^b>=a-b but it is not easy. We can think of, when they take equal, we know the difference or the same is 0, the difference is 1 then we put a, B with the binary expansion, so that we a, B is each corresponding, we put so different bits, all into ai = 1,bi = 0. So we know that there is no borrow so a^b = = B. Then the order of the XOR sequence changes, a-B becomes smaller, then the A^b>=a-b thereby c=a-b. The proposition is to be proven.
Prove whether the establishment, directly with A^b==a-b can. Yes, keep in the F array, F[i] represents the number of a=i cases. Finally, we ask for a prefix and both, and finally O1 find.
#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>#defineRep (i,j,k) for (int i=j;i<=k;i++)using namespacestd;Const intmaxx=30000001;intF[maxx];voidinit () { for(intI=1; i<=maxx/2; i++){ for(intj=2*i;j<=maxx;j+=i) { intb=j-i; if((j^b) = =i) {F[j]++; } } } for(intI=2; i<=maxx;i++) {F[i]+=f[i-1]; }}intMain () {intT; intN; intzz=0; scanf ("%d",&t); intCnt=0; intA; Memset (F,0,sizeof(f)); Init (); while(t--) {ZZ++; scanf ("%d",&N); printf ("Case %d:%d\n", Zz,f[n]); } return 0;}
UVA-12716-XOR sequence