[主席树维护HASH] Codechef. Cloning

来源:互联网 发布:手机上中文编程的软件 编辑:程序博客网 时间:2024/05/21 05:21

传送门

直接用主席树维护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;}
阅读全文
0 0
原创粉丝点击