暑假没过,今天打了下表发现了规律 ,然后就A
求Q,可以看出先让Q=(for i=1->n)(i mod 1)^...(i mod n);
然后for 一边把Q^=Pi
然后我把前面的打表出来发现竟然有规律
#include <cstring> #include <cstdio> #include <algorithm> using namespace std; int main(){ int n; int a[100][100]; scanf("%d",&n); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ a[i][j]=i%j; } } for(int i=1;i<n;i++){ for(int j=0;j<=n;j++){ printf("%d ",a[i][j]); } puts(""); } } /* 10 0 0 1 1 1 1 1 1 1 1 1 0 0 0 2 2 2 2 2 2 2 2 0 0 1 0 3 3 3 3 3 3 3 0 0 0 1 0 4 4 4 4 4 4 0 0 1 2 1 0 5 5 5 5 5 0 0 0 0 2 1 0 6 6 6 6 0 0 1 1 3 2 1 0 7 7 7 0 0 0 2 0 3 2 1 0 8 8 0 0 1 0 1 4 3 2 1 0 9 */
发现从第三列每次都有循环节,第零列是0(0)第一列是1(0),第二列是2(1 0),第三列是3(1 2 0)。。。。。
就可按照循环节算出前面的(for i=1->n)(i mod 1)^...(i mod n);,因为他就是这个矩阵
。。balabala。。。
代码如下
:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; #define N 1100000 ll ans; int n; ll a[N]; ll mod[N]; int num[N]; void init(){ mod[0]=0; for(int i=1;i<N;i++){ mod[i]=mod[i-1]^i; } } void work(int x){ memset(num,0,sizeof(num)); if(x==0||x==1) return ; for(int i=2;i<=x;i++){ num[i-1]+=x/i; num[x%i]++; } } int main(){ init(); ans=0; scanf("%d",&n); work(n); for(int i=1;i<n;i++){ if(num[i]&1){ ans^=mod[i]; } } ll b; while(n--){ scanf("%I64d",&b); ans^=b; } printf("%I64d\n",ans); }
时间: 2024-10-13 00:26:48