CF Magic Formulas (XOR运算)

来源:互联网 发布:发票验旧需要什么数据 编辑:程序博客网 时间:2024/06/15 16:06

题目大意:

首先给一个整数N,然后输入n个整数,p1,p2,...,pn;

qi = pi(xor)(i mod 1)(xor)(i mod 2)(xor)...(xor)(i mod n)  (i = 1,2,3,...,n);

Q = q1 (xor) q2 (xor) ... (xor) qn;

要求输出Q的值;

解题思路:

如果分别求出q1,q2,..qn的值的话,时间肯定会超时,通过化简可以看到:

Q = p1 (xor) p2 (xor) ... (xor) pn (xor)

       (1 mod 1) (xor) (1 mod 2) (xor) (1 mod 3) (xor) ... (xor) (1 mod n) (xor)

       (2 mod 1) (xor) (2 mod 2) (xor) (2 mod 3) (xor) ... (xor) (2 mod n) (xor)

       (3 mod 1) (xor) (3 mod 2) (xor) (3 mod 3) (xor) ... (xor) (3 mod n) (xor)

... ...
(n mod 1) (xor) (n mod 2) (xor) (n mod 3) (xor) ... (xor) (n mod n);

p1 ^ p2 ^ p3 ^ ... ^ pn是可求的,时间复杂度为O(n);

下面对取摸的那部分进行分析:

p1  0 ^ 1 ^ 1 ^ 1 ^ 1 ^ ... ^ 1

p2  0 ^ 0 ^ 2 ^ 2 ^ 2 ^ ... ^ 2

p3  0 ^ 1 ^ 0 ^ 3 ^ 3 ^ ... ^ 3

p4  0 ^ 0 ^ 1 ^ 0 ^ 4 ^ ... ^ 4

p5  0 ^ 1 ^ 2 ^ 1 ^ 0 ^ ... ^ 5

构成一个矩阵,上三角的每行的数字都是相同的,如果相同的数字做异或运算,数字个数为偶数,那么结果为0,数字个数为奇数,那么结果为数字本身;

下三角形:

0

0 ^ 0

0 ^ 1 ^ 0

0 ^ 0 ^ 1 ^ 0

0 ^ 1 ^ 2 ^ 1 ^ 0

现在从列考虑这个矩阵,每一列都是 0,1,...pi-1的循环排列,如果循环次数为偶数,则循环的异或运算结果为0,否则循环的异或运算结果为一个循环的异或结果。

然后异或上没有构成一个完整循环的数字的异或运算。可以通过打表的方法求出tmp[i],(tmp[i] = 0 ^ 1 ^ 2 ^ ... ^ i  (i=1,2,3,...,n));

代码:

#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#define M 1000005int p[M], tmp[M];int main(){    int n, ans;    while(~scanf("%d", &n)){        ans = 0;        for(int i=0; i<n; i++){            scanf("%d", &p[i]);            ans = ans ^ p[i];            if((n-i-1)%2) ans = ans ^ (i+1);        }        memset(tmp, 0, sizeof(tmp));        tmp[0] = 0;        for(int i=1; i<n;i++){            tmp[i] = tmp[i-1] ^ i;        }        int tmp1, tmp2;        for(int i=1; i<=n; i++){            tmp1 = (n-i+1)%i;            tmp2 = (n-i+1)/i;            if(tmp2%2) ans ^= tmp[i-1];            if(tmp1) ans ^= tmp[tmp1-1];        }        printf("%d\n", ans);    }    return 0;}


0 0
原创粉丝点击