您的位置:首页 > 其它

Codeforces 242(DIV 2) C题

2014-04-30 18:39 363 查看
C. Magic Formulas

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard output

People in the Tomskaya region like magic formulas very much. You can see some of them below.

Imagine you are given a sequence of positive integer numbers p1, p2, ..., pn.
Lets write down some magic formulas:





Here, "mod" means the operation of taking the residue after dividing.

The expression

means applying the bitwise xor (excluding "OR") operation to integers x and y.
The given operation exists in all modern programming languages. For example, in languages C++ and Java it is represented by "^", in Pascal — by "xor".

People in the Tomskaya region like magic formulas very much, but they don't like to calculate them! Therefore you are given the sequence p, calculate the value of Q.

Input
The first line of the input contains the only integer n (1 ≤ n ≤ 106). The next line contains n integers: p1, p2, ..., pn (0 ≤ pi ≤ 2·109).

Output
The only line of output should contain a single integer — the value of Q.

Sample test(s)

input
3
1 2 3


output
3

思路:对于本题,只需要知道公式中每个数异或了多少次,一个数与0异或还是它本身,因此同一个数异或奇数此等一一次,偶数次等于0次,比如a^a = 0,a^a^a = a,关键是怎么计算某个数被异或的次数?对于任意x,首先考虑x
mod y,(y > x),结果都是x,这样的y有(n-x)个,其次余数x还有其他来源,它们是比x大且对比x大的数取模,y mod z (y > x,z > x),只有这两种来源,第一种来源容易得到,第二种就需要动脑筋了,不然暴力算的话就会超时,想想,对于第二种 :y必然有这样的形式:y = z*n + x,(n属于正整数,而且z >= i+1),只有这样的y才符合要求,等价于:y-x = z*n,到这里,我们可以从1到n枚举,这样一算n不会太大,而且第二层for循环执行的次数减少的很快,只需要每次加上((y-x)/i-(y-x)/(i+1))*i,就能得出次数,最后看是奇数还是偶数即可。里面有很多小细节,写的时候就会发现,还要注意边界问题,讨论
t = (y-x)/(i+1) 等于1的情况。

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    int n, ans, tmp;
    while(~scanf("%d", &n)){
        ans = 0;
        for(int i = 0; i < n;i ++){
            scanf("%d", &tmp);
            ans ^= tmp;
        }
        for(int i = 1;i < n;i ++){
            int cnt = n-i;
            int t = (n-i)/(i+1);
            if(t == 1) cnt += (n-2*i);
            else if(t > 1)cnt += t*((n-i)/t-i);
            for(int j = 1;j <= t-1;j ++){
                cnt += j*((n-i)/j-(n-i)/(j+1));
            }
            if(cnt&1) ans ^= i;
        }
        printf("%d\n", ans);
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: