http://codeforces.com/problemset/problem/163/E
http://acm.hdu.edu.cn/showproblem.php?pid=4117
上面两题我都是用AC自动机 + 线段树写的
当我们用AC自动机解决DP 或者 统计问题的时候,如果要支持更新操作,就需要数据结构的帮忙了
比如codeforces 163E,背景是最简单的多串匹配,但是有一个特殊的地方是会删除一些字符串和重新恢复一些字符串,注意到我们在统计的时候其实就是沿着fail指针走,把所有的标记叠加起来,而fail指针构成了一棵fail树,所以我们在求当前节点的fail指针方向有多少个标记的时候不必一层层的fail上去了,对于每个点维护其到根的有效节点的个数即可,
当更新某个点的时候,就相当于这个点的子树到根的有效节点的个数都发生了变化,将树形结构变成线性结构,在线段树中更新即可
第二题是个DP题,也是类似的方法,在fail指针方向找一个最大的值进行DP的转移,利用线段树求极值
codeforces 163E
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
inline void Max(int &a,int b){if(b>a) a=b;}
const int M = 300010;
const int N = 20010;
const int CD = 26;
int fail[M];
int Q[M];
int ch[M][CD];
int ID[128];
int sz;
char S[M];
int node[M];
void Init(){
fail[0]=0;
memset(ch[0],0,sizeof(ch[0]));
sz=1;
for(int i=0;i<26;i++) ID[i+'a'] = i;
}
void Insert(char *s,int id) {
int p=0;
for(;*s;s++) {
int c=ID[*s];
if(!ch[p][c]) {
memset(ch[sz],0,sizeof(ch[sz]));
ch[p][c]=sz++;
}
p=ch[p][c];
}
node[id]=p;
}
void Construct(){
int *s=Q,*e=Q,v;
for(int i=0;i edge[M];
int n;
int pos[N];
int tot;
int mx[M<<2];
int lz[M<<2];
void pushup(int rt) {
mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
}
void pushdown(int rt) {
if(lz[rt]) {
Max(lz[rt<<1],lz[rt]);
Max(lz[rt<<1|1],lz[rt]);
Max(mx[rt<<1],lz[rt<<1]);
Max(mx[rt<<1|1],lz[rt<<1|1]);
lz[rt]=0;
}
}
void build(int l,int r,int rt) {
lz[rt] = mx[rt] = 0;
if(l==r) return ;
int m=l+r>>1;
build(lson);
build(rson);
}
void update(int L,int R,int val,int l,int r,int rt) {
if(L <= l && r <= R) {
Max(lz[rt],val);
Max(mx[rt],val);
return ;
}
pushdown(rt);
int m=l+r>>1;
if(L <= m) update(L,R,val,lson);
if(R > m) update(L,R,val,rson);
pushup(rt);
}
int query(int pos,int l,int r,int rt) {
if(l==r) {
return mx[rt];
}
pushdown(rt);
int m=l+r>>1;
if(pos <= m) return query(pos,lson);
return query(pos,rson);
}
int L[M],R[M],dp[M];
void dfs(int u){
L[u]=++tot;
for(int i=0;i0) AC(i,pos[i-1]+1,pos[i]);
Max(ans,dp[i]);
}
printf("Case #%d: %d\n",ca++,ans);
}
return 0;
}