思路
最小值为 a,说明从 0 到 a−1 一定必须选。
所以答案最小为 a。
设 pi 为从 0 至 i 所有的数的异或(即 0xor1xor2xor...xori)。
若 pa−1=b,则直接输出 a(0xor1xor2xor...xora−1)。
否则,由于异或具有已知 axorb=c,则 cxorb=a,axorc=b 的性质,可以推算出最后一个需要添加到序列中的数 k,然后根据情况:
-
k=a,输出 a+1。
-
k=a,输出 a+2。(序列中不能有 a)
写出来之后,有些代码出现了 UKE(实际上是 TLE)的现象,原因是这些代码有这一行:
for(int i=1
这一行的时间复杂度是 O(a),再加上前面 t 次询问,则总时间复杂度是 O(at)。
将 1≤t≤5×105,1≤a≤3×105 代入,则总时间复杂度是 O(1.5×1011),严重超时。
所以我们需要寻求更快的解法:
a=1,p1=1
a=2,p2=3
a=3,p3=0
a=4,p4=4
a=5,p5=1
a=6,p6=7
a=7,p7=0
a=8,p8=8
∀k(k≥0),则
a=4k+1,pa=1
a=4k+2,pa=a+1
a=4k+3,pa=0
a=4k,pa=a
则求 pi 的函数显而易见:
long long y(int k){
if(k%4==1)return 1;
if(k%4==2)return k+1;
if(k%4==3)return 0;
if(k%4==0)return k;
}
依此写出代码,此题终。
#include<iostream>
using namespace std;
long long a,b,t,ans,p;
long long y(int k){
if(k%4==1)return 1;
if(k%4==2)return k+1;
if(k%4==3)return 0;
if(k%4==0)return k;
}
int main(){
cin>>t;
while(t--){
cin>>a>>b;p=0;
if(y(a-1)==b){
cout<<a<<endl;
}
else{
if((y(a-1)^b)!=a)cout<<a+1<<endl;
else cout<<a+2<<endl;
}
}
return 0;
}