HDU 5565 Clarke and baton

Problem Description

Clarke is a patient with multiple personality disorder. One day, Clarke split into nn guys, named 11 to nn.
They will play a game called Lose Weight. Each of Clarkes has a weight a[i]a[i]. They have a baton which is always in the hand of who has the largest weight(if there are more than 2 guys have the same weight, choose the one who has the smaller order). The one who holds the baton needs to lose weight. i.e. a[i]a[i] decreased by 1, whereii is the guy who holds the baton.
Now, Clarkes know the baton will be passed qq times. They want to know each one's weight after finishing this game.

Input

The first line contains an integer T(1 \le T \le 10)T(1T10), the number of the test cases.
Each test case contains three integers n, q, seed(1 \le n, q \le 10000000, \sum n \le 20000000, 1 \le seed \le 10^9+6)n,q,seed(1n,q10000000,n20000000,1seed109+6)seedseed denotes the random seed.
a[i]a[i] generated by the following code.

long long seed;
int rand(int l, int r) {
    static long long mo=1e9+7, g=78125;
    return l+((seed*=g)%=mo)%(r-l+1);
}

int sum=rand(q, 10000000);
for(int i=1; i<=n; i++) {
    a[i]=rand(0, sum/(n-i+1));
    sum-=a[i];
}
a[rand(1, n)]+=sum;
Output

Each test case print a line with a number which is (b[1]+1) xor (b[2]+2) xor ... xor (b[n]+n)(b[1]+1)xor(b[2]+2)xor...xor(b[n]+n), where b[i]b[i] is the ithith Clarke's weight after finishing the game.

Sample Input
1
3 2 1
Sample Output
20303

Hint:
At first, a[1]=20701, a[2]=31075, a[3]=26351a[1]=20701,a[2]=31075,a[3]=26351.  
At the first time, a[2]a[2] decrease by 1.  
At the second time, a[2]a[2] decrease by 1.  
Finally, a[1]=20701, a[2]=31073, a[3]=26351a[1]=20701,a[2]=31073,a[3]=26351. So answer is (20701+1)xor(31073+2)xor(26351+3)=20303

(20701+1)xor(31073+2)xor(26351+3)=20303

模拟一下操作就好了

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 10000005;
const int base = 1e9 + 7;
int T, limit;
int n, q, a[maxn], ft[maxn], nt[maxn];
LL seed;

int rand(int l, int r) {
    static long long mo = 1e9 + 7, g = 78125;
    return l + ((seed *= g) %= mo) % (r - l + 1);
}

int main()
{
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d%d%I64d", &n, &q, &seed);
        int sum = rand(q, 10000000);
        limit = 0;
        for (int i = 1; i <= n; i++)
        {
            a[i] = rand(0, sum / (n - i + 1));
            sum -= a[i];
            limit = max(a[i], limit);
        }
        limit = max(limit, a[rand(1, n)] += sum);
        for (int i = 1; i <= max(limit, n); i++) ft[i] = nt[i] = 0;
        for (int i = 1; i <= n; i++)
        {
            if (ft[a[i]])
            {
                nt[i] = ft[a[i]];
                ft[a[i]] = i;
            }
            else ft[a[i]] = i;
        }
        int tot = 0;
        for (int i = limit, j; i; i--)
        {
            if (q >= tot) { q = q - tot; limit = i; }
            else break;
            for (j = ft[i]; j; j = nt[j]) tot++;
        }
        int ans = 0;
        for (int i = 1; i <= n; i++)
        if (a[i] >= limit) if (q) { ans ^= (limit + i - 1); q--; }
        else ans ^= (limit + i);
        else ans ^= a[i] + i;
        printf("%d\n", ans);
    }
    return 0;
}

你可能感兴趣的:(HDU)