比赛的时候找出规律了,但是找的有点慢了,写代码的时候出了问题,也没交对,还掉分了。。。。
还是先总结一下位移或的性质吧:
1、 交换律 a ^ b = b ^ a
2、 结合律 (a^b) ^ c = a ^ (b^c)
3、 0^a = a;
4、 a^a = 0; a^a^a = a;
5、 知道a,b,c中任意两个就能推知第三个.
a^b = c 两边同时与a异或得: a ^ (a^b) = a^c 即 0^b = a^c 亦即 b = a^c
四个也是一样 若d = a ^ b ^ c 则a = d ^ b ^ c
1 #include <iostream> 2 #include <cstdlib> 3 #include <cmath> 4 using namespace std; 5 const int maxn = 1000000+10; 6 7 __int64 p, ans, a[maxn]; 8 void init() 9 { 10 int i; 11 a[0] = 0; 12 for(i = 1; i < maxn; i++) 13 a[i] = (a[i-1]^i); 14 } 15 int main() 16 { 17 int n, i, x; 18 while(cin>>n) 19 { 20 init(); 21 ans = 0; 22 for(i = 1; i <= n; i++) 23 { 24 cin>>p; 25 ans ^= p; 26 } 27 for(i = 1; i <= n; i++) 28 { 29 if(n%(2*i) != 0) 30 { 31 x = n%(2*i); 32 if(x >= i) 33 { 34 ans ^= a[i-1]; 35 x -= i; 36 } 37 ans ^= a[x]; //把a[x]写成了x结果调试了一晚上 38 } 39 } 40 cout<<ans<<endl; 41 } 42 return 0; 43 }