题目链接:codeforces 768C
一个数组,每次先排序,再每隔个一个对x进行异或,k次操作之后,最大最小值是多少
如果用普通的排序,效率O(knlogn)
,1e5的数据会超时,但是题目里有一个条件:0<=a<=1000,也就是最大1024
所以可以用开一个数组,记录下每个数字出现的次数,这样就不需要排序了,效率k*1000
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1000+100, INF = 1e8;
int n, k, x, num[2][MAXN], a, mi, ma;
int main()
{
cin >> n >> k >> x;
mi = INF;
ma = -INF;
for(int i=0; i<n; ++i)
{
scanf("%d", &a);
++num[0][a];
mi = min(mi, a);
ma = max(ma, a);
}
for(int i=0; i<k; ++i)
{
memset(num[(i+1)&1], 0, sizeof(num[(i+1)&1]));
int now = 1;
for(int j=mi; j<=ma; ++j)
{
if(num[i&1][j])
{
a = j^x;
if((num[i&1][j]&1) == 0)
{
num[(i+1)&1][a] += num[i&1][j]/2;
num[(i+1)&1][j] += num[i&1][j]/2;
}
else if(now&1)
{
num[(i+1)&1][a] += num[i&1][j]/2+1;
num[(i+1)&1][j] += num[i&1][j]/2;
// cout << "i+1 " << i+1 << " " << a << " " << num[i][j] << endl;
}
else
{
num[(i+1)&1][a] += num[i&1][j]/2;
num[(i+1)&1][j] += num[i&1][j]/2+1;
}
now += num[i&1][j];
}
}
mi = INF;
ma = -INF;
for(int j=0; j<=1090; j++)
{
if(num[(i+1)&1][j])
{
mi = min(mi, j);
ma = max(ma, j);
}
}
}
cout << ma << " " << mi << endl;
return 0;
}