动态树链剖分

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #define inf -1u>>1
  6 using namespace std;
  7 const int maxn=50000+10;
  8 struct Tedge{int x,y,dist,next;}adj[maxn*2];int ms=0,fch[maxn];
  9 struct Edge{int from,to,dist;}ed[maxn];
 10 void AddEdge(int u,int v,int w){adj[++ms]=(Tedge){u,v,w,fch[u]};fch[u]=ms;return;}
 11 int dep[maxn],s[maxn],fa[maxn],son[maxn],p[maxn],top[maxn],minv[maxn*3],maxv[maxn*3],sumv[maxn*3],n,Q;
 12 void DFS(int u){//ms赋0!!!! 
 13     s[u]=1;dep[u]=dep[fa[u]]+1;
 14     for(int i=fch[u];i;i=adj[i].next){
 15         int v=adj[i].y;
 16         if(v==fa[u]) continue;
 17         fa[v]=u;
 18         DFS(v);
 19         if(s[son[u]]<s[v]) son[u]=v;
 20         s[u]+=s[v];
 21     } return;
 22 }
 23 void build(int u,int tp){
 24     top[u]=tp;p[u]=++ms;
 25     if(son[u]) build(son[u],tp);
 26     for(int i=fch[u];i;i=adj[i].next){
 27         int v=adj[i].y;
 28         if(v!=fa[u]&&v!=son[u]) build(v,v);
 29     } return;
 30 }
 31 int x,v,ql,qr;
 32 void update(int o,int L,int R){
 33     //printf("%d %d %d\n",o,L,R);
 34     //getchar();
 35     if(L==R) minv[o]=maxv[o]=sumv[o]=v;
 36     else{
 37         int lc=o<<1,rc=lc|1,M=L+R>>1;
 38         if(x<=M) update(lc,L,M);
 39         else update(rc,M+1,R);
 40         minv[o]=min(minv[lc],minv[rc]);
 41         maxv[o]=max(maxv[lc],maxv[rc]);
 42         sumv[o]=sumv[lc]+sumv[rc];
 43     } return;
 44 }
 45 int _min,_max,_sum;
 46 void query(int o,int L,int R){
 47     //printf("%d %d %d\n",o,L,R);
 48     if(ql<=L&&R<=qr){
 49         _min=min(_min,minv[o]);
 50         _max=max(_max,maxv[o]);
 51         _sum+=sumv[o];
 52     }
 53     else{
 54         int lc=o<<1,rc=lc|1,M=L+R>>1;
 55         if(ql<=M) query(lc,L,M);
 56         if(qr>M) query(rc,M+1,R);;
 57     } return;
 58 }
 59 void ask(int a,int b){
 60     _min=inf,_max=0,_sum=0;
 61     int f1=top[a],f2=top[b];
 62     while(f1!=f2){
 63         if(dep[f1]<dep[f2]) swap(f1,f2),swap(a,b);
 64         ql=p[f1];qr=p[a];
 65         query(1,1,n);
 66         a=fa[f1];f1=top[a];
 67     }
 68     if(a==b) return;
 69     if(dep[a]>dep[b]) swap(a,b);
 70     ql=p[son[a]];qr=p[b];//不懂 
 71     query(1,1,n);return;
 72 }
 73 inline int read(){
 74     int x=0,sig=1;char ch=getchar();
 75     while(!isdigit(ch)){if(ch=='-') sig=-1;ch=getchar();}
 76     while(isdigit(ch)) x=10*x+ch-'0',ch=getchar();
 77     return x*=sig;
 78 }
 79 inline void write(int x){
 80     if(x==0){putchar('0');return;}if(x<0) putchar('-'),x=-x;
 81     int len=0,buf[15];while(x) buf[len++]=x%10,x/=10;
 82     for(int i=len-1;i>=0;i--) putchar(buf[i]+'0');return;
 83 }
 84 void init(){
 85     n=read();
 86     for(int i=1;i<n;i++){
 87         int a=read(),b=read(),c=read();
 88         ed[i]=(Edge){a,b,c};
 89         AddEdge(a,b,c);
 90         AddEdge(b,a,c);
 91     }
 92     ms=0;DFS(1);build(1,1);
 93     for(int i=1;i<n;i++){
 94         if(dep[ed[i].to]<dep[ed[i].from]) swap(ed[i].from,ed[i].to);
 95         x=p[ed[i].to]; v=ed[i].dist;
 96         update(1,1,n);
 97     }
 98     Q=read();
 99     return;
100 }
101 void work(){
102     while(Q--){
103         int tp=read(),a=read(),b=read();
104         if(tp){
105             ask(a,b);
106             if(a!=b) printf("%d %d %d\n",_max,_min,_sum);
107             else puts("error");
108         }
109         else x=p[ed[a].to],v=b,update(1,1,n);
110     }
111     return;
112 }
113 void print(){
114     return;
115 }
116 int main(){
117     init();work();print();return 0;
118 }

 

posted @ 2015-04-21 20:03  AI_Believer  阅读(151)  评论(0编辑  收藏  举报