hdu 4117 GRE Words 11年成都现场赛

来源:互联网 发布:什么影视cms好 编辑:程序博客网 时间:2024/05/14 15:18

离线建树,然后按顺序把值插入,每插入一个值的时候就按着fail算出该节点的最优解。

一个优化,那些值小于0的节点直接去掉,这个代码不能保证ac,因为这个做法上界很高,但是这题貌似数据随机生成,偶尔能够ac。。。

这个题目正解的话,是要加上线段树来优化这个做法的,因为按照fail指针可以构造出一棵树,算最优解的过程就变成不断更新节点的所有孩子值,求节点的最大值。

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int maxn=3e5+9,N=26,root=0,maxm=2e4+9;int cas=0;int lon;struct{    int next[N],tmp,fail;}trie[290000];void clr(int t){    for(int i=0;i<N;i++) trie[t].next[i]=0;    trie[t].tmp=trie[t].fail=0;}void trieini(){    clr(0);    lon=0;}void insert(char s[]){    int t=root;    int n=strlen(s+1);    for(int i=1;i<=n;i++)    {        if(trie[t].next[s[i]-'a']==0)        {            trie[t].next[s[i]-'a']=++lon;            clr(lon);        }        t=trie[t].next[s[i]-'a'];    }}void getfail(){    queue <int> q;    q.push(root);    while(!q.empty())    {        int t=q.front();        q.pop();        for(int i=0;i<N;i++)        if(trie[t].next[i])        {            int u=trie[t].next[i];            int tmp=trie[t].fail;            while(tmp!=root&&trie[tmp].next[i]==0)            tmp=trie[tmp].fail;            trie[u].fail=trie[tmp].next[i];            if(t==root) trie[u].fail=root;            q.push(u);        }    }}int a[maxm];char s[maxn+21111];void solve(int top,int n){    int now=1;    for(int i=1,t=root,ret=0,u;now<=n;i++)    {        if(s[i]=='#')        {            trie[t].tmp=ret+a[now];            now++;            ret=0;            t=root;            continue;        }        t=trie[t].next[s[i]-'a'];        u=t;        while(u!=root)        {            ret=max(ret,trie[u].tmp);            u=trie[u].fail;        }    }    int ans=0;    for(int i=1;i<=lon;i++)    ans=max(ans,trie[i].tmp);    printf("Case #%d: %d\n",++cas,ans);}int main(){//    freopen("in.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--)    {        trieini();        int n,top=0,m;        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            scanf("%s %d",s+1+top,&a[i]);            if(a[i]<0)            {                i--;                n--;                continue;            }            insert(s+top);            m=strlen(s+1+top);            top+=m;            s[++top]='#';        }        getfail();        solve(top,n);    }    return 0;}


原创粉丝点击