[洛谷P4114]Qtree1:树链剖分,线段树

裸的不能再裸了。

注意将边的信息下放给点后的统计答案的方式。

代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 using namespace std;
  6 inline int read(){
  7     int x=0,f=1;char ch=getchar();
  8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  9     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
 10     return x*f;
 11 }
 12 const int MAXN=100005;
 13 const int INF=0x3f3f3f3f;
 14 int n,head[MAXN],ecnt,fa[MAXN],dep[MAXN],siz[MAXN],pc[MAXN],top[MAXN],id[MAXN],v[MAXN],w[MAXN];
 15 int tot,maxn[MAXN*4],loc,ql,qr,k;
 16 struct Edge{
 17     int frm,to,nxt,w;
 18 }e[MAXN*2];
 19 inline void add_edge(int bg,int ed,int val){
 20     ecnt++;
 21     e[ecnt].nxt=head[bg];
 22     e[ecnt].frm=bg;
 23     e[ecnt].to=ed;
 24     e[ecnt].w=val;
 25     head[bg]=ecnt;
 26 }
 27 void dfs1(int x,int pre,int depth){
 28     fa[x]=pre;
 29     dep[x]=depth;
 30     siz[x]=1;
 31     int maxsiz=-1;
 32     for(int i=head[x];i;i=e[i].nxt){
 33         int ver=e[i].to;
 34         if(ver==pre) continue;
 35         v[ver]=e[i].w;
 36         dfs1(ver,x,depth+1);
 37         siz[x]+=siz[ver];
 38         if(siz[ver]>maxsiz) maxsiz=siz[ver],pc[x]=ver;
 39     }
 40 }
 41 void dfs2(int x,int topf){
 42     top[x]=topf;
 43     id[x]=++tot;
 44     w[tot]=v[x];
 45     if(!pc[x]) return;
 46     dfs2(pc[x],topf);
 47     for(int i=head[x];i;i=e[i].nxt){
 48         int ver=e[i].to;
 49         if(ver==fa[x]||ver==pc[x]) continue;
 50         dfs2(ver,ver);
 51     }
 52 }
 53 #define mid ((l+r)>>1)
 54 #define lc (o<<1)
 55 #define rc ((o<<1)|1)
 56 void build(int o,int l,int r){
 57     if(l==r){
 58         maxn[o]=w[l];
 59         return;
 60     }
 61     build(lc,l,mid);
 62     build(rc,mid+1,r);
 63     maxn[o]=max(maxn[lc],maxn[rc]);
 64 }
 65 void upd(int o,int l,int r){
 66     if(l==r&&l==loc){
 67         maxn[o]=k;
 68         return;
 69     }
 70     if(loc<=mid) upd(lc,l,mid);
 71     else upd(rc,mid+1,r);
 72     maxn[o]=max(maxn[lc],maxn[rc]);
 73 }
 74 int query(int o,int l,int r){
 75     if(l>r) return -INF;
 76     if(ql<=l&&r<=qr) return maxn[o];
 77     int ans=-INF;
 78     if(mid>=ql) ans=max(ans,query(lc,l,mid));
 79     if(mid<qr) ans=max(ans,query(rc,mid+1,r));
 80     return ans;
 81 }
 82 inline int pathquery(int x,int y){
 83     if(x==y) return 0;
 84     int ans=-INF;
 85     while(top[x]!=top[y]){
 86         if(dep[top[x]]<dep[top[y]]) swap(x,y);
 87         ql=id[top[x]],qr=id[x];
 88         ans=max(ans,query(1,1,n));
 89         x=fa[top[x]];
 90     }
 91     if(dep[x]>dep[y]) swap(x,y);
 92     ql=id[x]+1,qr=id[y];
 93     ans=max(ans,query(1,1,n));
 94     return ans;
 95 }
 96 int main(){
 97     n=read();
 98     for(int i=1;i<n;i++){
 99         int u=read(),v=read(),w=read();
100         add_edge(u,v,w);
101         add_edge(v,u,w);
102     }
103     v[1]=-INF;
104     dfs1(1,0,1);
105     dfs2(1,1);
106     build(1,1,n);
107     while(1){
108         char opt[12];
109         scanf("%s",opt+1);
110         if(opt[1]=='D') break;
111         else if(opt[1]=='C'){
112             int x=read();k=read();
113             loc=(dep[e[x<<1].frm]<dep[e[x<<1].to]?id[e[x<<1].to]:id[e[x<<1].frm]);
114             upd(1,1,n);
115         }
116         else{
117             int x=read(),y=read();
118             printf("%d\n",pathquery(x,y));
119         }
120     }
121     return 0;
122 }

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9279215.html