题意:
有一个长度n的数列,琼恩有一个喜爱的数x,琼恩每次去隔一个 数对数列里的数异或,请问k次操作后数列里最大的数和最小的数分别是什么
解题思路:
这种题一般来说操作后的数列是有循环节的,然后看到群里qc爸爸问有没有循环节不是2的例子的时候就更确定了。先去模拟下操作,然后每次操作出来的数列都去和之前得到的数列比较,看看是否有相同的数列,如果有就找到循环节了,只要让k对应到这个循环节就可以求出答案
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n, k, x;
int a[maxn];
int b[104][maxn];
int c[maxn][3];
int main()
{
cin>>n>>k>>x;
int i, j=0;
c[j][0]=0;c[j][1]=maxn;
for(i=0; i<n; i++)
{
scanf("%d", &a[i]);
b[j][i]=a[i];
c[j][0]=b[j][i]>c[j][0]?b[j][i]:c[j][0];
c[j][1]=b[j][i]<c[j][1]?b[j][i]:c[j][1];
}
sort(a, a+n);
// for(i=0; i<n; i++)printf("%d ", a[i]);printf("\n");
j=1;
bool sam=true;
int s=0;
while(1)
{
for(i=0; i<n; i++)b[j][i]=b[j-1][i];
sort(b[j], b[j]+n);
for(i=0; i<n; i+=2){b[j][i]=b[j][i]^x;}
sort(b[j], b[j]+n);
sam=true;
c[j][0]=0;c[j][1]=maxn;
for(i=0; i<n; i++)
{
c[j][0]=b[j][i]>c[j][0]?b[j][i]:c[j][0];
c[j][1]=b[j][i]<c[j][1]?b[j][i]:c[j][1];
// printf("%d ", b[j][i]);
}
for(int e=1; e<j; e++)
{
sam=true;
for(i=0; i<n; i++)
{
sam&=(b[j][i]==b[e][i]);
// printf("%d %d %d\n", e, j, sam);
}
if(sam)
{
s=e;
break;
}
}
if(s)break;
// cout<<j<<endl;
j++;
// if(j>=19)break;
// if(j>10)break;
}
// printf("%d %d\n", s, j);
if(k<s)printf("%d %d\n", c[k][0], c[k][1]);
else
{
printf("%d %d\n",c[(k-s)%(j-s)+s][0], c[(k-s)%(j-s)+s][1]);
}
return 0;
}