hdu 5801 Up Sky,Mr.Zhu(2016多校第六场1009) 可持久化字典树

来源:互联网 发布:软件设计师 考试 编辑:程序博客网 时间:2024/06/06 03:52

因为只有20,所以我们按长度建可持久化字典树,然后询问时枚举长度即可,长度为奇数和偶数可以分开求。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>using namespace std;const int maxn=100105;int root[2][10][maxn];int cnt;namespace  Trie{    int sum[maxn*20];    int ch[maxn*20][5];    void init(){        cnt=0;        memset(root,0,sizeof(root));        memset(ch[0],0,sizeof(ch[0]));        sum[0]=0;    }    void insert(int pre,int no,char *t){        int p=strlen(t);        for(int i=0;i<p;i++){            for(int j=0;j<5;j++){                ch[no][j]=ch[pre][j];            }            int w=t[i]-'a';            ch[no][w]=++cnt;            no=ch[no][w];            pre=ch[pre][w];            sum[no]=sum[pre]+1;        }        for(int j=0;j<5;j++){            ch[no][j]=ch[pre][j];        }    }    int query(int pre,int no,char *t){        int p=strlen(t);        int flag=0;        for(int i=0;i<p;i++){            pre=ch[pre][t[i]-'a'];            no=ch[no][t[i]-'a'];            if(no==0) return 0;            if(pre==0){                flag=1;            }        }        if(flag) return sum[no];        return sum[no]-sum[pre];    }}char s[maxn];char t[20];int main(){    while(scanf("%s",s)!=EOF){        Trie::init();        int n;        n=strlen(s);        for(int j=n;j>=1;j--) s[j]=s[j-1];        for(int i=1;i<=10;i++){            for(int j=i;j+i-1<=n;j++){                int flag=0;                for(int f=j;f<=j+i-1;f++){                    if(s[f]!=s[2*j-f]){                        flag=1;                        break;                    }                    t[f-j]=s[f];                }                t[i]='\0';                if(flag==0){                    root[0][i-1][j]=++cnt;                    Trie::insert(root[0][i-1][j-1],cnt,t);                }                else{                    root[0][i-1][j]=root[0][i-1][j-1];                }            }            for(int j=i+1;j+i-1<=n;j++){                int flag=0;                for(int f=j;f<=j+i-1;f++){                    if(s[f]!=s[2*j-f-1]){                        flag=1;                        break;                    }                    t[f-j]=s[f];                }                t[i]='\0';                if(flag==0){                    root[1][i-1][j]=++cnt;                    Trie::insert(root[1][i-1][j-1],cnt,t);                }                else{                    root[1][i-1][j]=root[1][i-1][j-1];                }            }        }        int m;        scanf("%d",&m);        for(int i=0;i<m;i++){            int l,r;            scanf("%d%d",&l,&r);            scanf("%s",t);            int ans=0;            for(int j=1;j<=min((r-l+2)/2,10);j++){                int x=l+j-1;                int y=r-j+1;                if(x<=y){                    ans+=Trie::query(root[0][j-1][x-1],root[0][j-1][y],t);                }                if(x<y){                    ans+=Trie::query(root[1][j-1][x],root[1][j-1][y],t);                }            }            printf("%d\n",ans);        }    }}


0 0
原创粉丝点击