直接用主席树维护HASH比较就可以了吧…
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
typedef unsigned long long ll;
const int N=100010;
const ll base=100003;
int t,n,q,cnt;
int a[N],rt[N],ls[N*50],rs[N*50],tot[N*50];
ll v[N*50],p[N];
void Add(int &g,int l,int r,int x){
int k=g; g=++cnt; ls[g]=ls[k]; rs[g]=rs[k]; v[g]=v[k]; tot[g]=tot[k];
if(l==r){
v[g]++; tot[g]++; return ;
}
int mid=l+r>>1;
if(x<=mid) Add(ls[g],l,mid,x); else Add(rs[g],mid+1,r,x);
v[g]=v[ls[g]]*p[r-mid]+v[rs[g]]; tot[g]=tot[ls[g]]+tot[rs[g]];
}
inline int dif(int x,int y,int a,int b){
if(v[y]-v[x]==v[b]-v[a]) return 0;
int l=1,r=n;
while(l<r){
int mid=l+r>>1;
if(v[ls[y]]-v[ls[x]]==v[ls[b]]-v[ls[a]])
x=rs[x],y=rs[y],a=rs[a],b=rs[b],l=mid+1;
else
x=ls[x],y=ls[y],a=ls[a],b=ls[b],r=mid;
}
return l;
}
int Find(int x,int y,int L,int R,int l,int r){
if(v[x]-v[y]==0) return -1;
if(L==R) return tot[x]-tot[y]==0?-1:L;
int mid=L+R>>1;
if(l==L && r==R){
if(v[ls[x]]-v[ls[y]]) return Find(ls[x],ls[y],L,mid,l,mid);
else return Find(rs[x],rs[y],mid+1,R,mid+1,r);
}
if(r<=mid) return Find(ls[x],ls[y],L,mid,l,r);
else if(l>mid) return Find(rs[x],rs[y],mid+1,R,l,r);
int ret=Find(ls[x],ls[y],L,mid,l,mid);
if(~ret) return ret;
return Find(rs[x],rs[y],mid+1,R,mid+1,r);
}
int Check(int x,int y,int L,int R,int p){
if(L==R) return tot[x]-tot[y];
int mid=L+R>>1;
if(p<=mid) return Check(ls[x],ls[y],L,mid,p);
else return Check(rs[x],rs[y],mid+1,R,p);
}
int main(){
scanf("%d",&t);
p[0]=1; for(int i=1;i<=100000;i++) p[i]=p[i-1]*base;
while(t--){
scanf("%d%d",&n,&q); cnt=0;
for(int i=1;i<=n;i++) rt[i]=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]); rt[i]=rt[i-1];
Add(rt[i],1,n,a[i]);
}
for(int i=1;i<=q;i++){
int l1,r1,l2,r2;
scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
int pos=dif(rt[l1-1],rt[r1],rt[l2-1],rt[r2]);
if(!pos){
puts("YES");
continue;
}
int A=Check(rt[r1],rt[l1-1],1,n,pos),B=Check(rt[r2],rt[l2-1],1,n,pos);
if(A>B){
A=Find(rt[r1],rt[l1-1],1,n,pos,n); B=Find(rt[r2],rt[l2-1],1,n,pos+1,n);
}
else{
A=Find(rt[r1],rt[l1-1],1,n,pos+1,n); B=Find(rt[r2],rt[l2-1],1,n,pos,n);
}
int curA=rt[r1],curB=rt[r2],lst=cnt;
if(~A) Add(curB,1,n,A);
if(~B) Add(curA,1,n,B);
if(!dif(rt[l1-1],curA,rt[l2-1],curB)) puts("YES");
else puts("NO");
cnt=lst;
}
}
return 0;
}