题意:http://acm.hdu.edu.cn/showproblem.php?pid=4117
思路:https://blog.csdn.net/u013306830/article/details/77586562
主要就是卡你内存,AC自动机的字典树得要用了再清空。
代码有点长吧。。。
1 #include <cstdio>//sprintf islower isupper
2 #include <iostream>//pair
3 #include <string.h>//strstr substr strcat
4 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
5 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
6 #define mem(a,b) memset(a,b,sizeof(a))
7 #define pr printf
8 #define sc scanf
9 #define ls rt<<1
10 #define rs rt<<1|1
11 const int N=3e5+10;
12
13 char s[N];
14 int pos[20004],val[20004];
15 //-------------------------------
16 class mymap
17 {
18 public:
19 int tot;
20 int head[N];
21 int SZ[N];
22 int dfn[N],cnt;
23 struct
24 {
25 int to,next;
26 }edge[N];
27 void Init(int n)
28 {
29 tot=0;
30 cnt=-1;
31 for(int i=0;i<=n;++i)
32 head[i]=SZ[i]=0;
33 }
34 void add(int from,int to)
35 {
36 ++tot;
37 edge[tot].to=to;
38 edge[tot].next=head[from];
39 head[from]=tot;
40 }
41 int dfs(int u)
42 {
43 ++cnt;
44 dfn[u]=cnt;
45 SZ[dfn[u]]=1;
46 for(int i=head[u];i;i=edge[i].next)
47 {
48 // cout<<edge[i].first<<endl;
49 SZ[dfn[u]]+=dfs(edge[i].to);
50 }
51 return SZ[dfn[u]];
52 }
53 }TREE;
54
55 class seg_tree
56 {
57 public:
58 int max_[N<<2],add[N<<2];
59
60 void up(int rt)
61 {
62 max_[rt]=max(max_[ls],max_[rs]);
63 }
64 void dn(int rt)
65 {
66 if(add[rt])
67 {
68 add[ls]=max(add[ls],add[rt]);
69 add[rs]=max(add[rs],add[rt]);
70 max_[ls]=max(max_[ls],add[rt]);
71 max_[rs]=max(max_[rs],add[rt]);
72 add[rt]=0;
73 }
74 }
75 void Build(int l,int r,int rt)
76 {
77 max_[rt]=0;
78 add[rt]=0;
79 if(l==r)
80 {
81 return;
82 }
83 int mid=(l+r)>>1;
84
85 Build(l,mid,rt<<1);
86 Build(mid+1,r,rt<<1|1);
87 }
88 int Q_dot(int pos,int l,int r,int rt)
89 {
90 if(l==r)
91 {
92 return max_[rt];
93 }
94
95 int mid=(l+r)>>1;
96 dn(rt);
97 if(pos<=mid)
98 return Q_dot(pos,l,mid,rt<<1);
99 else
100 return Q_dot(pos,mid+1,r,rt<<1|1);
101 }
102 void update_qu(int L,int R,int V,int l,int r,int rt)
103 {
104 if(L>R)return;
105 if(L<=l&&r<=R)
106 {
107 max_[rt]=max(max_[rt],V);
108 add[rt]=max(add[rt],V);
109 return;
110 }
111
112 int mid=(l+r)>>1;
113 dn(rt);
114 if(L<=mid)
115 update_qu(L,R,V,l,mid,rt<<1);
116 if(R>mid)
117 update_qu(L,R,V,mid+1,r,rt<<1|1);
118 up(rt);
119 }
120 }SEG;
121
122 class ac_automaton
123 {
124 public:
125 int tot;
126 int trie[N][27];
127 int fail[N];
128 //other
129 //--------------
130 void Insert(int l,int r)
131 {
132 int rt=0;
133 for(int i=l;i<=r;++i)
134 {
135 int id=s[i]-'a'+1;
136 if(!trie[rt][id])
137 {
138 mem(trie[++tot],0);
139 trie[rt][id]=tot;
140 }
141 rt=trie[rt][id];
142 }
143 }
144 queue<int>q;
145 void Getfail()
146 {
147 for(int i=1;i<=26;++i)
148 {
149 int id=trie[0][i];
150 if(id)
151 {
152 fail[id]=0;
153 q.push(id);
154 }
155 }
156 while(!q.empty())
157 {
158 int rt=q.front();q.pop();
159 for(int i=1;i<=26;++i)
160 {
161 int id=trie[rt][i];
162 if(id)
163 {
164 fail[id]=trie[fail[rt]][i];
165 q.push(id);
166 }
167 else
168 trie[rt][i]=trie[fail[rt]][i];
169 }
170 }
171 }
172 int Find(int l,int r,int id,int n)
173 {
174 int rt=0;
175 int pos=0;
176 int temp_max=0;
177 for(int i=l;i<=r;++i)
178 {
179 rt=trie[rt][s[i]-'a'+1];
180 pos=TREE.dfn[rt];
181 int temp_val=SEG.Q_dot(pos,1,n,1)+val[id];
182 temp_max=max(temp_max,temp_val);
183 }
184 SEG.update_qu(pos,pos+TREE.SZ[pos]-1,temp_max,1,n,1);
185 // for(int j=1;j<=n;++j)pr("%d ",SEG.Q_dot(j,1,n,1));
186 // cout<<endl<<"----------------------------------"<<endl;
187 return temp_max;
188 }
189 }AC;
190
191 void solve()
192 {
193 AC.tot=0;
194 mem(AC.trie[0],0);
195 int n,tot;
196 sc("%d",&n);
197 pos[1]=1;
198 for(int i=1;i<=n;++i)
199 {
200 sc("%s %d",s+pos[i],&val[i]);
201 int l=strlen(s+pos[i]);
202 AC.Insert(pos[i],pos[i]+l-1);
203 pos[i+1]=pos[i]+l;
204 }
205 tot=AC.tot;
206 // pr("%s\n",s+1);
207 AC.Getfail();
208 TREE.Init(tot);
209 SEG.Build(1,tot,1);
210 for(int i=1;i<=AC.tot;++i)
211 TREE.add(AC.fail[i],i);
212 TREE.SZ[0]=TREE.dfs(0);
213 int ans=0;
214 for(int i=1;i<=n;++i)
215 ans=max(ans,AC.Find(pos[i],pos[i+1]-1,i,tot));
216 pr("%d\n",ans);
217 }
218
219 int main()
220 {
221 int T,cnt=0;
222 sc("%d",&T);
223 while(T--)
224 {
225 pr("Case #%d: ",++cnt);
226 solve();
227 }
228 return 0;
229 }
230
231 /**************************************************************************************/
来源:https://www.cnblogs.com/--HPY-7m/p/11960478.html