[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
");
85         else printf("Yes
");
86     }
87     return 0;
88 }
View Code
原文地址:https://www.cnblogs.com/Ngshily/p/5001535.html