SPOJ 375 Query on a tree 树链剖分模板

第一次写树剖~


#include<iostream> #include<cstring> #include<cstdio> #define L(u) u<<1 #define R(u) u<<1|1 using namespace std; const int MAX=10005; int t,head[MAX*2],next1[MAX*2],tov[MAX*2],val[MAX*2],tot,n; int fa[MAX],w[MAX],son[MAX],depth[MAX],tot2,size[MAX]; int d[MAX][5],tree[MAX*4],top[MAX]; char ch[10]; inline void swap(int &a,int &b) { int t; t=a; a=b; b=t; } inline void add(int a,int b,int c) { tot++; next1[tot]=head[a]; head[a]=tot; tov[tot]=b; val[tot]=c; } inline void dfs1(int k) { son[k]=0; size[k]=1; for (int i=head[k];i;i=next1[i]) { int v=tov[i]; if (v!=fa[k]) { fa[v]=k; depth[v]=depth[k]+1; dfs1(v); son[k]=size[v]<size[son[k]]?son[k]:v; size[k]+=size[v]; } } } inline void dfs2(int k,int _top) { w[k]=++tot2; top[k]=_top; if (son[k]!=0) dfs2(son[k],_top);//the same _top for (int i=head[k];i;i=next1[i]) { int v=tov[i]; if (v!=fa[k]&&v!=son[k]) dfs2(v,v);//the new _top; } } inline void update(int u,int l,int r,int loc,int _value) { if (l==loc&&r==loc) { tree[u]=_value; return ; } int mid=(l+r)>>1; if (loc<=mid) update(L(u),l,mid,loc,_value); else update(R(u),mid+1,r,loc,_value); tree[u]=max(tree[R(u)],tree[L(u)]);//pushup } void doit() { memset(head,0,sizeof(head)); memset(depth,0,sizeof(depth)); memset(fa,0,sizeof(fa)); memset(tree,0,sizeof(tree)); tot2=tot=0; scanf("%d",&n); for (int i=1;i<=n-1;i++) { scanf("%d%d%d",&d[i][0],&d[i][1],&d[i][2]); add(d[i][0],d[i][1],d[i][2]); add(d[i][1],d[i][0],d[i][2]); } dfs1(1); dfs2(1,1); for (int i=1;i<=n-1;i++) { if (depth[d[i][0]]>depth[d[i][1]]) swap(d[i][0],d[i][1]);//make the higher depth node to map the Edge update(1,1,tot2,w[d[i][1]],d[i][2]); //change the value of the loc->w[d[i][1]] } } inline int query(int u,int l,int r,int l1,int r1) { if (l1<=l&&r1>=r) return tree[u]; int mid=(l+r)>>1; if (r1<=mid) return query(L(u),l,mid,l1,r1); else if (l1>mid) return query(R(u),mid+1,r,l1,r1); else { return max(query(L(u),l,mid,l1,r1),query(R(u),mid+1,r,l1,r1)); } } int findans(int va,int vb) { int f1,f2,ans; f1=top[va]; f2=top[vb]; ans=0; while (f1!=f2)//find lca { if (depth[f1]<depth[f2]) { swap(f1,f2); swap(va,vb); } ans=max(ans,query(1,1,tot2,w[f1],w[va]));//swap make w[f1]<w[f2] if (f1==f2) return ans;//in the same chain va=fa[f1];f1=top[va]; } if (va==vb) return ans; if (depth[va]>depth[vb]) swap(va,vb); return max(ans,query(1,1,tot2,w[son[va]],w[vb]));//the last do the f1=top[va] } void read() { ch[0]='G'; scanf("%s",ch); } void work() { for (read();ch[0]!='D';read()) { int x,y; scanf("%d%d",&x,&y); if (ch[0]=='Q') printf("%d\n",findans(x,y)); else update(1,1,tot2,w[d[x][1]],y); } } int main() { scanf("%d",&t); for (int i=1;i<=t;i++) { doit(); work(); } }

 

posted @ 2016-10-25 16:38  love★maple  阅读(130)  评论(0编辑  收藏  举报