hdu 4426 Palindromic Substring

来源:互联网 发布:js分享到微信朋友圈 编辑:程序博客网 时间:2024/06/10 12:58

因为每个串的不同回文子串数目是O(n)的,考虑求出不同的子串及其数目,显然回文树可以搞,构建完回文树之后按照最长回文后缀边产生的拓扑序下推标记,查询时直接dfs整棵树求出每个串的value后排序即可。

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;#define clr(a) memset(a,0,sizeof(a))typedef long long ll;const ll md=777777777;char cz[100010];int n,m,tn,nx[100010][26],px[100010],le[100010],dg[100010],ar[26];ll fr[100010],sm[100010],fg[100010];struct bi{ll a,b;}xr[100010];bool bimp(const bi&a,const bi&b){return a.a<b.a;};void pshd(int v){    if(px[v]>1)fg[px[v]]+=fg[v],sm[px[v]]+=fg[v];    fg[v]=0;};void _cl(){    int i,j,t,tn,lst;clr(dg),clr(nx[0]),clr(nx[1]),px[1]=0,le[0]=-1,le[1]=0;    for(tn=i=1,lst=0;i<=n;++i){        for(t=cz[i]-'a',j=lst;cz[i]!=cz[i-le[j]-1];j=px[j]);        if(nx[j][t]){lst=nx[j][t];sm[lst]++,fg[lst]++;}        else{            lst=++tn;clr(nx[tn]),le[tn]=le[j]+2,nx[j][t]=tn,sm[tn]=fg[tn]=1;            for(j=px[j];cz[i]!=cz[i-le[j]-1];j=px[j]);            px[tn]=le[tn]>1?nx[j][t]:1;if(px[tn]>1)dg[px[tn]]++;        }    }    queue<int>qe;for(i=2;i<=tn;++i)if(!dg[i])qe.push(i);    for(;!qe.empty();){        t=qe.front();qe.pop();pshd(t),dg[px[t]]--;        if(px[t]>1&&!dg[px[t]])qe.push(px[t]);    }};void _clfr(){    int i;for(fr[0]=1,i=1;i<=100000;++i)        fr[i]=fr[i-1]*26%md;};void dfs(int v,ll x,int d){    if(d){xr[tn].a=x,xr[tn].b=sm[v];++tn;}    int i;for(i=0;i<26;++i)if(nx[v][i]){        dfs(nx[v][i],(x+fr[d]*ar[i])%md,d+1);    }};void cl(){    int i;ll j,k;scanf("%d %d",&n,&m);scanf("%s",cz+1);    for(_cl();m;m--){        for(scanf("%I64d",&k),i=0;i<26;scanf("%d",&ar[i++]));        tn=0;dfs(0,0,0),dfs(1,0,0);sort(xr,xr+tn,bimp);        for(i=j=0;;++i){            j+=xr[i].b;            if(j>=k){printf("%I64d\n",xr[i].a);break;}        }    }    putchar('\n');};int main(){#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    freopen("out.txt","w",stdout);#endif    int t;for(_clfr(),scanf("%d",&t);t;t--,cl());    return 0;};
0 0
原创粉丝点击