题目链接:http://codeforces.com/contest/768/problem/C
题意:给出n个数,k个操作,和一个x,每次操作先排序然后对奇数位数进行xor x操作,最后问k次操作后最大值和最小值
为多少。
题解:看似是要找规律的但是只要暴力就行了。主要是a[i]的范围就只有10的3次,而且时间还有4s,直接来一个vis[i]表示
0~2048个数内取了几个,这样排序都不用了。直接for 0~2048就行。(2的10次1024,异或2的9次就是,2的11次减1
所以设最大为2048)然后稍微处理一下。可能还会用到一个re[i]辅助数组,具体看一下代码。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int M = 1e5 + 10;
int a[M];
int vis[M] , re[M];
int main() {
int n , k , x;
scanf("%d%d%d" , &n , &k , &x);
for(int i = 0 ; i <= 2048 ; i++) {
vis[i] = 0;
re[i] = 0;
}
for(int i = 0 ; i < n ; i++) {
scanf("%d" , &a[i]);
vis[a[i]]++;
re[a[i]]++;
}
if(n == 1) {
if(k % 2 == 0) {
printf("%d %d\n" , a[0] , a[0]);
}
else {
printf("%d %d\n" , (a[0] ^ x) , (a[0] ^ x));
}
}
else {
for(int i = 0 ; i < k ; i++) {
int flag = 0;
for(int j = 0 ; j <= 2048 ; j++) {
if(vis[j]) {
if(!flag) {
int gg = (vis[j] + 1) / 2;
re[j] -= gg;
re[(j ^ x)] += gg;
flag += vis[j];
flag %= 2;
continue;
}
else {
int gg = vis[j] / 2;
re[j] -= gg;
re[(j ^ x)] += gg;
flag += vis[j];
flag %= 2;
continue;
}
}
}
for(int j = 0 ; j <= 2048 ; j++) {
vis[j] = re[j];
}
}
for(int j = 2048 ; j >= 0 ; j--) {
if(vis[j]) {
printf("%d " , j);
break;
}
}
for(int j = 0 ; j <= 2048 ; j++) {
if(vis[j]) {
printf("%d\n" , j);
break;
}
}
}
return 0;
}