终于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 }