[BZOJ3207]花神的嘲讽计划Ⅰ
先把长度为k的字符串哈希掉,然后用可持久化线段树判断是否存在。。。
可持久化线段树直接上模板,然而哈希。。。
这里有三种哈希方法:①排个序,去个重,查找的时候二分
②hash[i]=hash[i-1]*大质数+val[i]
③鬼畜查字符版哈希
下面的代码是第一种,然而加了读入优化更慢是什么鬼QAQ
1 #include<stdio.h> 2 #include<ctype.h> 3 #include<algorithm> 4 using namespace std; 5 6 #define maxn 100005 7 int tot,tree[maxn*20],Lson[maxn*20],Rson[maxn*20],root[maxn]; 8 int nn,n,m,k,val[maxn],yooo[maxn],hash[maxn],pos[maxn]; 9 int read(){ 10 char ch=0; 11 int tmp=0; 12 while(!isdigit(ch))ch=getchar(); 13 while(isdigit(ch)){ 14 tmp=tmp*10+ch-'0'; 15 ch=getchar(); 16 } 17 return tmp; 18 } 19 bool cmp(int x,int y){ 20 for(int i=0;i<k;i++){ 21 if(val[x+i]<val[y+i])return true; 22 if(val[x+i]>val[y+i])return false; 23 } 24 return false; 25 } 26 int cmp2(int x){ 27 for(int i=0;i<k;i++){ 28 if(val[x+i]<yooo[i])return -1; 29 if(val[x+i]>yooo[i])return 1; 30 } 31 return 0; 32 } 33 bool buyiyang(int x,int y){ 34 for(int i=0;i<k;i++) 35 if(val[x+i]!=val[y+i])return true; 36 return false; 37 } 38 void build(int x,int &y,int l,int r,int val){ 39 tree[y=++tot]=tree[x]+1; 40 if(l==r)return; 41 int mid=(l+r)>>1; 42 if(val<=mid){ 43 Rson[y]=Rson[x]; 44 build(Lson[x],Lson[y],l,mid,val); 45 } 46 else{ 47 Lson[y]=Lson[x]; 48 build(Rson[x],Rson[y],mid+1,r,val); 49 } 50 } 51 bool query(int x,int y,int l,int r,int val){ 52 if(!(tree[y]-tree[x]))return false; 53 if(l==r)return true; 54 int mid=(l+r)>>1; 55 if(val<=mid)return query(Lson[x],Lson[y],l,mid,val); 56 else return query(Rson[x],Rson[y],mid+1,r,val); 57 } 58 int main(){ 59 freopen("1.in","r",stdin); 60 scanf("%d%d%d",&n,&m,&k); 61 for(int i=1;i<=n;i++){ 62 scanf("%d",&val[i]); 63 pos[i]=i; 64 } 65 sort(pos+1,pos+1+n,cmp); 66 hash[pos[1]]=++nn; 67 for(int i=2;i<=n;i++){ 68 nn+=buyiyang(pos[i-1],pos[i]); 69 hash[pos[i]]=nn; 70 } 71 for(int i=1;i<=n-k+1;i++) 72 build(root[i-1],root[i],1,nn,hash[i]); 73 for(int i=1;i<=m;i++){ 74 int ql,qr; 75 scanf("%d%d",&ql,&qr); 76 for(int j=0;j<k;j++) 77 scanf("%d",&yooo[j]); 78 int l=0,r=n+1; 79 while(l<r-1){ 80 int mid=(l+r)>>1; 81 if(cmp2(pos[mid])<=0)l=mid; 82 else r=mid; 83 } 84 if(!cmp2(pos[l])&&query(root[ql-1],root[qr-k+1],1,nn,hash[pos[l]]))printf("No\n"); 85 else printf("Yes\n"); 86 } 87 return 0; 88 }