[主席树 Hash] Codechef JUNE17 #CLONEME Cloning

来源:互联网 发布:cmd删除windows.old 编辑:程序博客网 时间:2024/06/05 18:09

对权值建主席树 然后对于区间[a,b],[c,d]
在主席树上二分排完序后从左第一个不一样的地方 以及从右第一个不一样的地方
这个可以Hash下权值的出现次数,也是可以相减的

#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;typedef unsigned long long ull;inline char nc(){  static char buf[100000],*p1=buf,*p2=buf;  return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void read(int &x){  char c=nc(),b=1;  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=100005;const int M=10000005;const int maxn=1e5;int rt[N],ncnt;int ls[M],rs[M];ull H[M]; int sum[M];ull seed[N];inline void add(int &x,int y,int l,int r,int t){  x=++ncnt;  if (l==r){    sum[x]=sum[y]+1; H[x]=sum[x]; return;  }  int mid=(l+r)>>1;  if (t<=mid) add(ls[x],ls[y],l,mid,t),rs[x]=rs[y];  else add(rs[x],rs[y],mid+1,r,t),ls[x]=ls[y];  H[x]=H[ls[x]]+seed[mid-l+1]*H[rs[x]];  sum[x]=sum[ls[x]]+sum[rs[x]];}int Ret=0;inline void queryL(int a,int b,int c,int d,int l,int r){  if (H[b]-H[a]==H[d]-H[c]){ Ret+=sum[b]-sum[a]; return; }  if (l==r){    Ret+=min(sum[b]-sum[a],sum[d]-sum[c]);    return;  }  int mid=(l+r)>>1;  if (H[ls[b]]-H[ls[a]]==H[ls[d]]-H[ls[c]]){    Ret+=sum[ls[b]]-sum[ls[a]];    queryL(rs[a],rs[b],rs[c],rs[d],mid+1,r);  }else    queryL(ls[a],ls[b],ls[c],ls[d],l,mid);}inline void queryR(int a,int b,int c,int d,int l,int r){  if (H[b]-H[a]==H[d]-H[c]){ Ret+=sum[b]-sum[a]; return; }  if (l==r){    Ret+=min(sum[b]-sum[a],sum[d]-sum[c]);    return;  }  int mid=(l+r)>>1;  if (H[rs[b]]-H[rs[a]]==H[rs[d]]-H[rs[c]]){    Ret+=sum[rs[b]]-sum[rs[a]];    queryR(ls[a],ls[b],ls[c],ls[d],l,mid);  }else    queryR(rs[a],rs[b],rs[c],rs[d],mid+1,r);}int n,val[N];int main(){  int T;  freopen("t.in","r",stdin);  freopen("t.out","w",stdout);  read(T); seed[0]=1; for (int i=1;i<=maxn;i++) seed[i]=seed[i-1]*233333;  while (T--){    ncnt=0; int Q,a,b,c,d;    read(n); read(Q);    for (int i=1;i<=n;i++)      read(val[i]),add(rt[i],rt[i-1],1,maxn,val[i]);    while (Q--){      read(a); read(b); read(c); read(d);      int lret,rret;      Ret=0;      queryL(rt[a-1],rt[b],rt[c-1],rt[d],1,maxn);      lret=Ret;      Ret=0;      queryR(rt[a-1],rt[b],rt[c-1],rt[d],1,maxn);      rret=Ret;      if ((lret==b-a+1) || (lret+rret+1==b-a+1))    printf("YES\n");      else    printf("NO\n");    }  }  return 0;}
原创粉丝点击