再会 树剖

 终于AC:([SPOJ-QTREE],VJudge

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 using namespace std;
  5 #define maxn 10010
  6 struct Edge{
  7     int u,v,w,next;
  8 }e[maxn*2];
  9 struct Node{
 10     int l,r,val;
 11     Node *lc,*rc;
 12 }*root=NULL;
 13 int t,n,m,head[maxn*2],js,p,siz[maxn];
 14 int fa[maxn],son[maxn],dep[maxn],top[maxn],pos[maxn];
 15 //fa=父亲 son=重孩子 top=所在重链的链顶
 16 //pos在线段树中的位置 siz以v为顶的子树的孩子数
 17 void memsett(){
 18     js=0,p=0;
 19     memset(head,0,sizeof(head));
 20     memset(e,0,sizeof(e));
 21     memset(son,0,sizeof(son));
 22 }
 23 void Add_Edge(int u,int v,int w){
 24     e[++js].u=u;e[js].v=v;e[js].w=w;
 25     e[js].next=head[u];head[u]=js;
 26 }
 27 void DFS(int now,int f,int deepth){
 28     fa[now]=f;dep[now]=deepth;siz[now]=1;
 29     for(int i=head[now];i;i=e[i].next){
 30         int v=e[i].v;
 31         if(v!=f){
 32             DFS(v,now,deepth+1);siz[now]+=siz[v];
 33             if(!son[now]||siz[son[now]]<siz[v])
 34                 son[now]=v;
 35         }
 36     }
 37 }
 38 void GetTop(int u,int tp){
 39     top[u]=tp;pos[u]=++p;
 40     if(!son[u])return ;
 41     GetTop(son[u],tp);
 42     for(int i=head[u];i;i=e[i].next){
 43         int v=e[i].v;
 44         if(v!=son[u]&&v!=fa[u]) GetTop(v,v);
 45     }
 46 }
 47 void Build(Node * &pt,int l,int r){
 48     pt=new(Node);pt->l=l;pt->r=r;pt->val=0;
 49     if(l==r){
 50         pt->lc=pt->rc=NULL;return;
 51     }
 52     int mid=(l+r)/2;
 53     Build(pt->lc,l,mid);Build(pt->rc,mid+1,r);
 54 }
 55 void UpDate(Node *p,int ps,int val){
 56     if(p->l==p->r){ p->val=val;return; }
 57     int mid=(p->l+-p->r)/2;
 58     if(ps<=mid)UpDate(p->lc,ps,val);
 59     else UpDate(p->rc,ps,val);
 60     p->val=max(p->lc->val,p->rc->val);
 61 }
 62 int query(Node * p,int l,int r){
 63     if(l<=p->l&&p->r<=r)return p->val;
 64     int mid=(p->l+p->r)/2;
 65     int ans=0;
 66     if(l<=mid)ans=max(ans,query(p->lc,l,r));
 67     if(r>mid)ans=max(ans,query(p->rc,l,r));
 68     return ans;
 69 }
 70 int Find(int u,int v){
 71     int tp1=top[u],tp2=top[v],ans=0;
 72     while(tp1!=tp2){
 73         if(dep[tp1]<dep[tp2]){
 74             swap(tp1,tp2);swap(u,v);
 75         }
 76         ans=max(ans,query(root,pos[tp1],pos[u]));
 77         u=fa[tp1];tp1=top[u];
 78     }
 79     if(u==v) return ans;
 80     if(dep[u]>dep[v]) swap(u,v);
 81     return max(ans,query(root,pos[u]+1,pos[v]));
 82 } 
 83 int main()
 84 {
 85     scanf("%d",&t);
 86     while(t--){
 87         memsett();
 88         scanf("%d",&n);
 89         for(int i=1,x,y,z;i<=n-1;i++){
 90             scanf("%d%d%d",&x,&y,&z);
 91             Add_Edge(x,y,z);Add_Edge(y,x,z);
 92         }
 93         DFS(1,0,1);
 94         GetTop(1,1);
 95         Build(root,1,p);
 96         for(int i=1;i<=2*n-2;i+=2){
 97             if(dep[e[i].v]<dep[e[i].u]) swap(e[i].v,e[i].u); 
 98             UpDate(root,pos[e[i].v],e[i].w);
 99         }
100         char s[15];int u,v;
101         while(scanf("%s",s)==1){
102             if(s[0]=='D')break;
103             scanf("%d%d",&u,&v);
104             if(s[0]=='Q')printf("%d
",Find(u,v));
105             else UpDate(root,pos[e[u*2-1].v],v);
106         }
107     }
108     return 0;
109 }

AC:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 using namespace std;
  5 struct edge{
  6     int u,v,w,next;
  7 }e[20010];
  8 struct node{
  9     int l,r,val;
 10     node *lc,*rc;
 11 }*root=NULL;
 12 int t,n,m,head[10010],js,p;
 13 int fa[10010],son[10010],dep[10010],top[10010],pos[10010],siz[10010];
 14 // fa存他的父亲 son存他的重孩子 dep它的深度 top他所在重链的链顶 
 15 //pos在线段树中的位置 siz[v]以v为顶的子树的孩子数 
 16 void memsett()
 17 {
 18     js=0;p=0;
 19     memset(head,0,sizeof(head));
 20     memset(e,0,sizeof(e));
 21     memset(son,0,sizeof(son));
 22 }
 23 void add_edge(int u,int v,int w)
 24 {
 25     e[++js].u=u;e[js].v=v;e[js].w=w;
 26     e[js].next=head[u];head[u]=js;
 27 }
 28 void dfs(int u,int f,int d){
 29     fa[u]=f;dep[u]=d;siz[u]=1;
 30     for(int i=head[u];i;i=e[i].next){
 31         int v=e[i].v;
 32         if(v!=f){
 33             dfs(v,u,d+1);
 34             siz[u]+=siz[v];
 35             if(!son[u]||siz[son[u]]<siz[v])
 36               son[u]=v;
 37         }
 38     }
 39 }
 40 void gettop(int u,int tp)
 41 {
 42     top[u]=tp;pos[u]=++p;
 43     if(!son[u]) return;
 44     gettop(son[u],tp);
 45     for(int i=head[u];i;i=e[i].next)
 46     {
 47         int v=e[i].v;
 48         if(v!=son[u]&&v!=fa[u])
 49           gettop(v,v);
 50     }
 51 }
 52 void build(node * &pt,int l,int r){
 53      pt=new(node);
 54      pt->l=l;pt->r=r;pt->val=0;
 55      if(l==r){
 56          pt->lc=pt->rc=NULL;
 57          return ;
 58      }
 59      int mid=(l+r)/2;
 60      build(pt->lc,l,mid);
 61      build(pt->rc,mid+1,r);
 62 }
 63 void update(node * p,int ps,int val){
 64     if(p->l==p->r){
 65         p->val=val;return;
 66     }
 67     int mid=(p->l+p->r)/2;
 68     if(ps<=mid) update(p->lc,ps,val);
 69     else update(p->rc,ps,val);
 70     p->val=max(p->lc->val,p->rc->val);
 71 }
 72 int query(node * p,int l,int r)
 73 {
 74     if(l<=p->l&&p->r<=r)return p->val;
 75     int mid=(p->l+p->r)/2;
 76     int ans=0;
 77     if(l<=mid)ans=max(ans,query(p->lc,l,r));
 78     if(r>mid)ans=max(ans,query(p->rc,l,r));
 79     return ans;
 80 }
 81 int find(int u,int v)
 82 {
 83     int tp1=top[u],tp2=top[v],ans=0;
 84     while(tp1!=tp2)
 85     {
 86         if(dep[tp1]<dep[tp2])
 87         {
 88             swap(tp1,tp2);swap(u,v);
 89         }
 90         ans=max(ans,query(root,pos[tp1],pos[u]));
 91         u=fa[tp1];tp1=top[u];
 92     }
 93     if(u==v) return ans;
 94     if(dep[u]>dep[v]) swap(u,v);
 95     return max(ans,query(root,pos[u]+1,pos[v]));
 96 } 
 97 int main()
 98 {
 99     scanf("%d",&t);
100     while(t--)
101     {
102         memsett();
103         scanf("%d",&n);
104         for(int i=1;i<=n-1;i++)
105         {
106             int x,y,z;
107             scanf("%d%d%d",&x,&y,&z);
108             add_edge(x,y,z);add_edge(y,x,z);
109         }
110         dfs(1,0,1);
111         gettop(1,1);
112         build(root,1,p);
113         for(int i=1;i<2*n-2;i+=2)// 建边表时见了两遍 
114         {
115             if(dep[e[i].v]<dep[e[i].u]) swap(e[i].v,e[i].u);// 让v在下面 
116             update(root,pos[e[i].v],e[i].w);
117         }
118         char s[15];int u,v;
119         while(scanf("%s",s)==1)
120         {
121             if(s[0]=='D') break;
122             scanf("%d%d",&u,&v);
123             if(s[0]=='Q') printf("%d
",find(u,v));// 查询从u到v所经过的最大边权 
124             else update(root,pos[e[u*2-1].v],v);// 将第u条边的权值修改为v 
125         }
126     }
127     return 0;
128 }
原文地址:https://www.cnblogs.com/suishiguang/p/6416087.html