题意: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 ",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 ",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 /**************************************************************************************/