luogu4114 Qtree (树链剖分)

板子题..明天补树刨做法

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<vector>
  5 #include<queue>
  6 #include<cmath>
  7 #include<ctime>
  8 #define LL long long int
  9 #define inf 0x3f3f3f3f
 10 using namespace std;
 11 const int maxn=100010;
 12 
 13 LL rd(){
 14    LL x=0;char c=getchar();int neg=1;
 15    while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
 16    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
 17    return x*neg;
 18 }
 19 
 20 struct Edge{
 21     int a,b,l,ne;
 22 }eg[maxn*2];
 23 int N;
 24 int egh[maxn],ect;
 25 int wson[maxn],fa[maxn],dep[maxn];
 26 int val[maxn],num[maxn],root[maxn],top[maxn],het[maxn];
 27 int ch[maxn*3][2],v[maxn*4],pct;
 28 
 29 inline void adeg(int a,int b,int l){
 30     eg[ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];egh[a]=ect++;
 31 }
 32 
 33 int dfs1(int x,int f){
 34     int ma=-inf,mi=0,re=1;fa[x]=f;dep[x]=dep[f]+1;
 35     for(int i=egh[x];i!=-1;i=eg[i].ne){
 36         int b=eg[i].b;if(b==f) continue;
 37         int c=dfs1(b,x);re+=c;
 38         val[b]=max(val[b],eg[i].l);
 39         if(c>ma) ma=c,mi=b;
 40     }wson[x]=mi;return re;
 41 }
 42 
 43 inline void update(int p){v[p]=max(v[ch[p][0]],v[ch[p][1]]);}
 44 
 45 void build(int &p,int l,int r){
 46     p=++pct;if(l==r) v[p]=val[num[l]];
 47     else{
 48         int m=l+r>>1;
 49         build(ch[p][0],l,m);build(ch[p][1],m+1,r);
 50         update(p);
 51     }
 52 }
 53 void change(int p,int l,int r,int x,int y){
 54     if(l==r) v[p]=y;
 55     else{
 56         int m=l+r>>1;
 57         if(x<=m) change(ch[p][0],l,m,x,y);
 58         else change(ch[p][1],m+1,r,x,y);
 59         update(p);
 60     }
 61 }
 62 int query(int p,int l,int r,int x,int y){
 63     if(x<=l&&r<=y) return v[p];
 64     else{
 65         int m=l+r>>1,re=-inf;
 66         if(x<=m) re=max(re,query(ch[p][0],l,m,x,y));
 67         if(y>=m+1) re=max(re,query(ch[p][1],m+1,r,x,y));
 68         return re;
 69     }
 70 }
 71 
 72 void dfs2(int x,int f){
 73     if(wson[f]!=x){int i,j;
 74         for(i=1,j=x;j;j=wson[j],i++) num[i]=j,top[j]=x;
 75         het[x]=i-1;build(root[x],1,het[x]);
 76     }for(int i=egh[x];i!=-1;i=eg[i].ne){
 77         int b=eg[i].b;if(b==f) continue;
 78         dfs2(b,x);
 79     }
 80 }
 81 
 82 void solveC(int a,int b){
 83     int x=eg[a*2-1].a,y=eg[a*2-1].b;
 84     if(dep[x]<dep[y]) swap(x,y);
 85     change(root[top[x]],1,het[top[x]],dep[x]-dep[top[x]]+1,b);
 86 }
 87 
 88 int solveQ(int x,int y){
 89     int re=-inf;if(x==y) return 0;
 90     while(top[x]!=top[y]){
 91         if(dep[top[x]]<dep[top[y]]) swap(x,y);
 92         re=max(re,query(root[top[x]],1,het[top[x]],1,dep[x]-dep[top[x]]+1));
 93         x=fa[top[x]];
 94     }if(x==y) return re;
 95     if(dep[x]>dep[y]) swap(x,y);
 96     return max(re,query(root[top[x]],1,het[top[x]],dep[x]-dep[top[x]]+2,dep[y]-dep[top[x]]+1));
 97 }
 98 
 99 int main(){
100     //freopen("4114.in","r",stdin);
101     int i,j,k;
102     char s[20];
103     N=rd();memset(egh,-1,sizeof(egh));
104     for(i=1;i<N;i++){
105         int a=rd(),b=rd(),c=rd();
106         adeg(a,b,c);adeg(b,a,c);
107     }dfs1(1,0);dfs2(1,0);
108     while(1){
109         scanf("%s",s);if(s[0]=='D') break;
110         i=rd(),j=rd();
111         if(s[0]=='C') solveC(i,j);
112         else printf("%d\n",solveQ(i,j));
113     }
114     return 0;
115 }

猜你喜欢

转载自www.cnblogs.com/Ressed/p/9404318.html