标签:
//Accepted 2280 KB 688 ms /* source:poj3237 time :2015.5.29 by :songt */ /*题解: 树链剖分 基于边权,路径查询最大值 线段树开到3倍RE,开到4倍AC */ #include <cstdio> #include <cstring> const int imax_n = 10005; const int inf = 0x3f3f3f3f; int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } void swap(int &a,int &b) { int t=a; a=b; b=t; } struct Edge { int u,v; Edge(){} Edge(int u,int v):u(v),v(v){} }edge[2*imax_n]; int head[imax_n]; int next[2*imax_n]; int tot; void addEdge(int u,int v) { edge[tot]=Edge(u,v); next[tot]=head[u]; head[u]=tot++; } int fa[imax_n],deep[imax_n],num[imax_n],son[imax_n]; int p[imax_n],fp[imax_n],top[imax_n]; int pos; void init() { memset(head,-1,sizeof(head)); memset(next,-1,sizeof(next)); tot=0; memset(son,-1,sizeof(son)); pos=0; } void dfs1(int u,int pre,int depth) { fa[u]=pre; deep[u]=depth; num[u]=1; for (int i=head[u];i+1;i=next[i]) { int v=edge[i].v; if (v!=pre) { dfs1(v,u,depth+1); num[u]+=num[v]; if (son[u]==-1 || num[son[u]]<num[v]) son[u]=v; } } } void dfs2(int u,int sp) { p[u]=pos++; fp[p[u]]=u; top[u]=sp; if (son[u]==-1) return ; dfs2(son[u],sp); for (int i=head[u];i+1;i=next[i]) { int v=edge[i].v; if (v!=fa[u] && v!=son[u]) { dfs2(v,v); } } } struct Tree { int l,r; int tmax,tmin; int rev; }f[imax_n*4]; void build(int t,int l,int r) { f[t].l=l; f[t].r=r; f[t].tmax=f[t].tmin=0; f[t].rev=0; if (l==r) { return ; } int mid=(f[t].l+f[t].r)>>1; build(2*t,l,mid); build(2*t+1,mid+1,r); } void push_down(int t) { f[2*t].rev^=1; f[2*t+1].rev^=1; int tmp=f[2*t].tmax; f[2*t].tmax=-f[2*t].tmin; f[2*t].tmin=-tmp; tmp=f[2*t+1].tmax; f[2*t+1].tmax=-f[2*t+1].tmin; f[2*t+1].tmin=-tmp; f[t].rev=0; } void push_up(int t) { f[t].tmax=max(f[2*t].tmax,f[2*t+1].tmax); f[t].tmin=min(f[2*t].tmin,f[2*t+1].tmin); } void update(int t,int k,int value) { if (f[t].l==k && f[t].r==k) { f[t].tmax=f[t].tmin=value; return ; } if (f[t].rev) push_down(t); int mid=(f[t].l+f[t].r)>>1; if (k<=mid) update(2*t,k,value); else update(2*t+1,k,value); push_up(t); } void reverse(int t,int l,int r) { if (f[t].l==l && f[t].r==r) { f[t].rev^=1; int tmp=f[t].tmax; f[t].tmax=-f[t].tmin; f[t].tmin=-tmp; return ; } if (f[t].rev) push_down(t); int mid=(f[t].l+f[t].r)>>1; if (r<=mid) reverse(2*t,l,r); else { if (l>mid) reverse(2*t+1,l,r); else { reverse(2*t,l,mid); reverse(2*t+1,mid+1,r); } } push_up(t); } int query(int t,int l,int r) { if (f[t].l==l && f[t].r==r) { return f[t].tmax; } if (f[t].rev) push_down(t); int mid=(f[t].l+f[t].r)>>1; if (r<=mid) return query(2*t,l,r); else { if (l>mid) return query(2*t+1,l,r); else return max(query(2*t,l,mid),query(2*t+1,mid+1,r)); } } void Re(int u,int v) { int f1=top[u],f2=top[v]; while (f1!=f2) { if (deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } reverse(1,p[f1],p[u]); u=fa[f1]; f1=top[u]; } if (u==v) return ; if (deep[u]>deep[v]) swap(u,v); reverse(1,p[son[u]],p[v]); } int find(int u,int v) { int f1=top[u],f2=top[v]; int ans=-inf; while (f1!=f2) { if (deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } ans=max(ans,query(1,p[f1],p[u])); u=fa[f1]; f1=top[u]; } if (u==v) return ans; if (deep[u]>deep[v]) swap(u,v); ans=max(ans,query(1,p[son[u]],p[v])); //printf("query %d %d\n",son[u],v); return ans; } char op[10]; int n,m; int u,v,c; int e[imax_n][3]; int main() { int T; scanf("%d",&T); while (T--) { scanf("%d",&n); init(); for (int i=0;i<n-1;i++) { scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]); addEdge(e[i][0],e[i][1]); addEdge(e[i][1],e[i][0]); } dfs1(1,0,0); dfs2(1,1); build(1,0,pos-1); for (int i=0;i<n-1;i++) { if (deep[e[i][0]]<deep[e[i][1]]) swap(e[i][0],e[i][1]); update(1,p[e[i][0]],e[i][2]); } while (scanf("%s",op)==1) { if (strcmp(op,"DONE")==0) break; scanf("%d%d",&u,&v); if (op[0]==‘Q‘) { printf("%d\n",find(u,v)); } else if (op[0]==‘N‘) { Re(u,v); } else if (op[0]==‘C‘) { update(1,p[e[u-1][0]],v); } } } return 0; }
标签:
原文地址:http://www.cnblogs.com/djingjing/p/4539562.html