大二训练第一周 F - Remember the Word trie树加dp

来源:互联网 发布:网狐6603手机捕鱼源码 编辑:程序博客网 时间:2024/06/15 10:17


大白书上说 dp[i]=sum(dp[i]+dp[i+len(x)]初始化dp[len]=1然后递推回去

ACcode:

#pragma warning(disable:4786)//使命名长度不受限制#pragma comment(linker, "/STACK:102400000,102400000")//手工开栈#include <map>#include <set>#include <queue>#include <cmath>#include <stack>#include <cctype>#include <cstdio>#include <cstring>#include <stdlib.h>#include <iostream>#include <algorithm>#define rd(x) scanf("%d",&x)#define rd2(x,y) scanf("%d%d",&x,&y)#define rds(x) scanf("%s",x)#define rdc(x) scanf("%c",&x)#define ll long long int#define maxn 100005#define mod 20071027#define INF 0x3f3f3f3f //int 最大值#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;++i)#define MT(x,i) memset(x,i,sizeof(x))#define PI  acos(-1.0)#define E  exp(1)#define MAX 26using namespace std;struct Trie{    bool v;    Trie *next[MAX];};Trie *root;void creatTrie(char *str){    Trie *p=root,*q;    int len=strlen(str);    FOR(i,0,len-1){        int id=str[i]-'a';        if(p->next[id]==NULL){            q=(Trie *)malloc(sizeof(Trie));            FOR(i,0,MAX-1)q->next[i]=NULL;            q->v=false;            p->next[id]=q;            p=p->next[id];        }        else {            p=p->next[id];        }    }    p->v=true;}int dp[300010];void qurey(int k,int m,char *str){    Trie *p=root;    for(int i=k;i<m;++i){        int id=str[i]-'a';        if(p->next[id]!=NULL){            if(p->next[id]->v==true){                dp[k]=(dp[k]+dp[i+1])%mod;            }            p=p->next[id];        }        else            return;    }}int doit(char *str){    int m=strlen(str);MT(dp,0);dp[m]=1;    for(int i=m-1;i>=0;--i){            qurey(i,m,str);    }    return dp[0];}char str[300010];char t[4010];int cnt=1,q;int main(){    while(rds(str)!=EOF){        root=(Trie *)malloc(sizeof(Trie));        FOR(i,0,MAX-1)root->next[i]=NULL;        rd(q);FOR(i,1,q){rds(t);creatTrie(t);}        printf("Case %d: %d\n",cnt++,doit(str));    }    return 0;}/*abcd4abcdab*/


0 0
原创粉丝点击