用了离散化+可持久化线段树(说白了是个可持久化数组)维护 n 个数的出现次数前缀和。 然后后面查询的时候有一个二分,所以复杂度 O(nlog2n)。
但是赛时 pretest TLE On #15 了。不知道是的确会被卡还是复杂度假了。
所以求助各位大佬指出一下代码的问题或者讲一下能不能把这个二分优化掉()
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
inline int read(){
int ret=0;
char c=getchar();
while(!('0'<=c&&c<='9')) c=getchar();
while('0'<=c&&c<='9') ret=(ret<<1)+(ret<<3)+(c^48),c=getchar();
return ret;
}
int T,n,m,Q;
const int N=2e5+10;
int a[N],b[N];
inline int getid(int x){
int l=1,r=m,mid;
while(l<r){
mid=(l+r)>>1;
if(b[mid]>=x) r=mid;
else l=mid+1;
}
return l;
}
struct NODE{
int ls,rs;
int cnt;
} tr[N*18];
int idx=0,rt[N];
int modify(int u,int l,int r,int k){
int v=++idx;
tr[v]=tr[u];
if(l==r){
tr[v].cnt++;
return v;
}
int mid=(l+r)>>1;
if(k<=mid) tr[v].ls=modify(tr[u].ls,l,mid,k);
else tr[v].rs=modify(tr[u].rs,mid+1,r,k);
return v;
}
int query(int u,int l,int r,int k){
if(!u) return 0;
if(l==r) return tr[u].cnt;
int mid=(l+r)>>1;
if(k<=mid) return query(tr[u].ls,l,mid,k);
else return query(tr[u].rs,mid+1,r,k);
}
int main(){
T=read();
while(T--){
idx=0;
n=read(),Q=read();
for(int i=1;i<=n;i++){
a[i]=a[i-1]^read();
b[i]=a[i];
}
b[n+1]=a[0];
sort(b+1,b+2+n);
m=(unique(b+1,b+2+n)-b)-1;
a[0]=getid(a[0]);
for(int i=1;i<=n;i++){
a[i]=getid(a[i]);
rt[i]=modify(rt[i-1],1,m,a[i]);
}
int x,y;
int l,r,mid;
while(Q--){
x=read(),y=read();
if(a[y]==a[x-1]){
puts("YES");
continue;
}
else{
int R=query(rt[y],1,m,a[x-1]);
if(query(rt[x-1],1,m,a[x-1])==R){
puts("NO");
continue;
}
l=x,r=y;
while(l<r){
mid=(l+r)>>1;
if(query(rt[mid],1,m,a[x-1])==R) r=mid;
else l=mid+1;
}
R=query(rt[r],1,m,a[y]);
if(query(rt[x-1],1,m,a[y])==R) puts("NO");
else puts("YES");
}
}
}
return 0;
}