调了一个晚上
代码又臭又长
为什么zjoi2011的题目都是代码量那么大的题…
考虑在一条链上的情况,可以用线段树记录一个区间的八个值
然后维护瞎维护一下……
那么用树链剖分就可以把树上的情况转化成多个链的情况
树链剖分求一条(u,v)的路径的时候(u,lca)的路径要反转后再链上(v,lca)
这里和维护的部分坑了我一个晚上……
果然代码写的长就容易错……
#include
#include
#include
#define N 30010
using namespace std;
int n,m,cnt,g,u,v;
int p[N],q[N],G[N],fa[N],top[N],son[N],siz[N],dpt[N];
char A[N],B[N];
char op;
struct edge{
int t,nx;
}E[N<<1];
struct stp{
int lara,larb,lbra,lbrb,Max,Empty,la,lb,ra,rb;
stp(){lara=larb=lbra=lbrb=Max=Empty=la=lb=ra=rb=0;}
friend stp operator +(stp a,stp b){
stp r;
if(a.lara&&b.lara) r.lara=a.lara+b.lara; if(a.larb&&b.lbra) r.lara=max(r.lara,a.larb+b.lbra);
if(a.lara&&b.larb) r.larb=a.lara+b.larb; if(a.larb&&b.lbrb) r.larb=max(r.larb,a.larb+b.lbrb);
if(a.lbra&&b.lara) r.lbra=a.lbra+b.lara; if(a.lbrb&&b.lbra) r.lbra=max(r.lbra,a.lbrb+b.lbra);
if(a.lbra&&b.larb) r.lbrb=a.lbra+b.larb; if(a.lbrb&&b.lbrb) r.lbrb=max(r.lbrb,a.lbrb+b.lbrb);
r.la=max(r.lara,r.larb); r.ra=max(r.lara,r.lbra); r.la=max(r.la,a.la); r.ra=max(r.ra,b.ra);
r.lb=max(r.lbra,r.lbrb); r.rb=max(r.larb,r.lbrb); r.lb=max(r.lb,a.lb); r.rb=max(r.rb,b.rb);
if(a.lara&&b.la) r.la=max(a.lara+b.la,r.la);
if(a.larb&&b.lb) r.la=max(r.la,a.larb+b.lb);
if(a.lbra&&b.la) r.lb=max(a.lbra+b.la,r.lb);
if(a.lbrb&&b.lb) r.lb=max(r.lb,a.lbrb+b.lb);
if(b.lara&&a.ra) r.ra=max(r.ra,b.lara+a.ra);
if(b.lbra&&a.rb) r.ra=max(r.ra,b.lbra+a.rb);
if(b.larb&&a.ra) r.rb=max(r.rb,b.larb+a.ra);
if(b.lbrb&&a.rb) r.rb=max(r.rb,b.lbrb+a.rb);
if(a.Empty||b.Empty) r.Empty=1;
r.Max=max(r.la,r.lb);
return r;
}
inline stp reverse(){
stp r=*this;
swap(r.larb,r.lbra);
swap(r.la,r.ra);
swap(r.lb,r.rb);
return r;
}
};
struct seg{
int l,r;
stp w;
}T[N<<2];
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if(p1==p2){p2=(p1=buf)+fread(buf,1,100000,stdin);if(p1==p2) return EOF;}
return *p1++;
}
inline void reaD(int &x){
char c=nc(); x=0;
for(;c>57||c<48;c=nc());for(;c>=48&&c<=57;x=x*10+c-48,c=nc());
}
inline void reaD(char &x){
while((x=nc())!=46&&x!=35&&x!='Q'&&x!='C');
}
inline void Insert(int x,int y){
E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
E[++cnt].t=x; E[cnt].nx=G[y]; G[y]=cnt;
}
void dfs0(int x,int f){
fa[x]=f; dpt[x]=dpt[f]+1; siz[x]=1;
for(int i=G[x];i;i=E[i].nx)
if(E[i].t!=f){
dfs0(E[i].t,x);
if(siz[E[i].t]>siz[son[x]]) son[x]=E[i].t;
siz[x]+=siz[E[i].t];
}
}
void dfs1(int x,int tp){
top[x]=tp; p[q[x]=++g]=x;
if(son[x]) dfs1(son[x],tp);
for(int i=G[x];i;i=E[i].nx)
if(E[i].t!=fa[x]&&E[i].t!=son[x]) dfs1(E[i].t,E[i].t);
}
inline void set(int g,int x){
T[g].w.lara=(A[p[x]]=='.');
T[g].w.lbrb=(B[p[x]]=='.');
if(A[p[x]]=='.'&&B[p[x]]=='.') T[g].w.larb=T[g].w.lbra=2;
else T[g].w.larb=T[g].w.lbra=0;
T[g].w.la=max(T[g].w.lara,T[g].w.larb); T[g].w.lb=max(T[g].w.lbra,T[g].w.lbrb);
T[g].w.ra=max(T[g].w.lara,T[g].w.lbra); T[g].w.rb=max(T[g].w.larb,T[g].w.lbrb);
if(A[p[x]]=='#'&&B[p[x]]=='#') T[g].w.Empty=1; else T[g].w.Empty=0;
T[g].w.Max=max(T[g].w.la,T[g].w.ra);
}
void build(int g,int l,int r){
T[g].l=l; T[g].r=r;
if(l==r) return set(g,l);
int mid=l+r>>1;
build(g<<1,l,mid);
build(g<<1|1,mid+1,r);
T[g].w=T[g<<1].w+T[g<<1|1].w;
}
stp query(int g,int l,int r){
if(T[g].l==l&&T[g].r==r) return T[g].w;
int mid=T[g].l+T[g].r>>1;
if(r<=mid) return query(g<<1,l,r);
if(l>mid) return query(g<<1|1,l,r);
return query(g<<1,l,mid)+query(g<<1|1,mid+1,r);
}
inline int query(int x,int y){
int lara=0,larb=0,lbra=0,lbrb=0;
int a=x,b=y,lca;
while(top[a]!=top[b])
if(dpt[top[a]]else a=fa[top[a]];
lca=dpt[a]1; bool fir=1;
for(;top[x]!=top[lca];x=fa[top[x]])
if(fir)L=query(1,q[top[x]],q[x]).reverse(),fir=0;
else L=L+query(1,q[top[x]],q[x]).reverse();
if(fir)L=query(1,q[lca],q[x]).reverse();
else L=L+query(1,q[lca],q[x]).reverse(); fir=1;
for(;top[y]!=top[lca];y=fa[top[y]])
if(fir) R=query(1,q[top[y]],q[y]),fir=0;
else R=query(1,q[top[y]],q[y])+R;
if(y!=lca)
if(fir) R=query(1,q[lca]+1,q[y]);
else R=query(1,q[lca]+1,q[y])+R;
return (L+R).Max;
}
void update(int g,int x){
if(T[g].l==T[g].r) return set(g,x);
int mid=T[g].l+T[g].r>>1;
if(x<=mid) update(g<<1,x);
else update(g<<1|1,x);
T[g].w=T[g<<1].w+T[g<<1|1].w;
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
reaD(n); reaD(m);
for(int i=1;i0(1,0); dfs1(1,1);
for(int i=1;i<=n;i++)
reaD(A[i]),reaD(B[i]);
build(1,1,g);
for(int i=1;i<=m;i++){
reaD(op);
if(op=='Q'){
reaD(u); reaD(v);
printf("%d\n",query(u,v));
}
else{
reaD(u); reaD(A[u]); reaD(B[u]);
update(1,q[u]);
}
}
}