woc这该死的码农题……
把每一条边转化为它连接的两点中深度较深的那一个,然后就可以用树剖+线段树对路径进行修改了
然后顺便注意在上面这种转化之后,树剖的时候不能搞$LCA$
然后是几个注意点
1.线段树记两个标记,一个区间覆盖,一个区间加和
2.区间覆盖的标记更新后要把区间加和的标记删除,因为覆盖后之前的加和相当于都废了
3.因为上面那个原因,pushdown的时候先下传区间覆盖标记再下传区间加和标记
4.标记更新的时候记得把答案也一起更新
5.数组开大一点!!!
1 //minamoto 2 #include<bits/stdc++.h> 3 using namespace std; 4 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} 5 inline int read(){ 6 #define num ch-'0' 7 char ch;bool flag=0;int res; 8 while(!isdigit(ch=getchar())) 9 (ch=='-')&&(flag=true); 10 for(res=num;isdigit(ch=getchar());res=res*10+num); 11 (flag)&&(res=-res); 12 #undef num 13 return res; 14 } 15 char sr[1<<21],z[20];int C=-1,Z; 16 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 17 inline void print(int x){ 18 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 19 while(z[++Z]=x%10+48,x/=10); 20 while(sr[++C]=z[Z],--Z);sr[++C]=' '; 21 } 22 const int N=2e5+5; 23 int head[N],Next[N<<1],ver[N<<1],edge[N<<1],tot=1; 24 inline void add_edge(int u,int v,int e){ 25 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e; 26 } 27 int dfn[N],sz[N],son[N],fa[N],dep[N],num[N],top[N],val[N],cnt,n; 28 void dfs1(int u){ 29 sz[u]=1,dep[u]=dep[fa[u]]+1; 30 for(int i=head[u];i;i=Next[i]){ 31 int v=ver[i]; 32 if(v!=fa[u]){ 33 fa[v]=u,num[i>>1]=v,dfs1(v),sz[u]+=sz[v]; 34 if(sz[son[u]]<sz[v]) son[u]=v; 35 } 36 } 37 } 38 void dfs2(int u,int t){ 39 dfn[u]=++cnt,top[u]=t; 40 if(son[u]){ 41 dfs2(son[u],t); 42 for(int i=head[u];i;i=Next[i]){ 43 int v=ver[i]; 44 if(v!=fa[u]&&v!=son[u]) dfs2(v,v); 45 } 46 } 47 } 48 int mx[N<<2],all[N<<2],add[N<<2]; 49 #define ls (p<<1) 50 #define rs (p<<1|1) 51 inline void upd(int p){mx[p]=max(mx[ls],mx[rs]);} 52 inline void pd(int p){ 53 if(~all[p]){ 54 all[ls]=all[rs]=mx[ls]=mx[rs]=all[p]; 55 add[ls]=add[rs]=0; 56 all[p]=-1; 57 } 58 if(add[p]){ 59 add[ls]+=add[p],add[rs]+=add[p]; 60 mx[ls]+=add[p],mx[rs]+=add[p]; 61 add[p]=0; 62 } 63 } 64 void build(int p,int l,int r){ 65 all[p]=-1,add[p]=0; 66 if(l==r) return (void)(mx[p]=val[l]); 67 int mid=(l+r)>>1; 68 build(ls,l,mid),build(rs,mid+1,r); 69 upd(p); 70 } 71 void change(int p,int l,int r,int x){ 72 if(l==r) return (void)(mx[p]=val[l]); 73 int mid=(l+r)>>1;pd(p); 74 x<=mid?change(ls,l,mid,x):change(rs,mid+1,r,x); 75 upd(p); 76 } 77 void update(int p,int l,int r,int ql,int qr,int x){ 78 if(ql<=l&&qr>=r) return (void)(all[p]=x,add[p]=0,mx[p]=x); 79 int mid=(l+r)>>1;pd(p); 80 if(ql<=mid) update(ls,l,mid,ql,qr,x); 81 if(qr>mid) update(rs,mid+1,r,ql,qr,x); 82 upd(p); 83 } 84 void ADD(int p,int l,int r,int ql,int qr,int x){ 85 if(ql<=l&&qr>=r) return (void)(add[p]+=x,mx[p]+=x); 86 int mid=(l+r)>>1;pd(p); 87 if(ql<=mid) ADD(ls,l,mid,ql,qr,x); 88 if(qr>mid) ADD(rs,mid+1,r,ql,qr,x); 89 upd(p); 90 } 91 int query(int p,int l,int r,int ql,int qr){ 92 if(ql<=l&&qr>=r) return mx[p]; 93 int mid=(l+r)>>1,res=0;pd(p); 94 if(ql<=mid) cmax(res,query(ls,l,mid,ql,qr)); 95 if(qr>mid) cmax(res,query(rs,mid+1,r,ql,qr)); 96 return res; 97 } 98 inline void Change(int k,int x){ 99 val[dfn[num[k]]]=x,change(1,1,n,dfn[num[k]]); 100 } 101 void Cover(int u,int v,int x){ 102 while(top[u]!=top[v]){ 103 if(dep[top[u]]<dep[top[v]]) swap(u,v); 104 update(1,1,n,dfn[top[u]],dfn[u],x); 105 u=fa[top[u]]; 106 } 107 if(u==v) return; 108 if(dep[u]<dep[v]) swap(u,v); 109 update(1,1,n,dfn[son[v]],dfn[u],x); 110 } 111 void Add(int u,int v,int x){ 112 while(top[u]!=top[v]){ 113 if(dep[top[u]]<dep[top[v]]) swap(u,v); 114 ADD(1,1,n,dfn[top[u]],dfn[u],x); 115 u=fa[top[u]]; 116 } 117 if(u==v) return; 118 if(dep[u]<dep[v]) swap(u,v); 119 ADD(1,1,n,dfn[son[v]],dfn[u],x); 120 } 121 int get(int u,int v){ 122 int res=0; 123 while(top[u]!=top[v]){ 124 if(dep[top[u]]<dep[top[v]]) swap(u,v); 125 cmax(res,query(1,1,n,dfn[top[u]],dfn[u])); 126 u=fa[top[u]]; 127 } 128 if(u==v) return res; 129 if(dep[u]<dep[v]) swap(u,v); 130 cmax(res,query(1,1,n,dfn[son[v]],dfn[u])); 131 return res; 132 } 133 int main(){ 134 // freopen("testdata.in","r",stdin); 135 n=read(); 136 for(int i=1,u,v,e;i<n;++i) 137 u=read(),v=read(),e=read(),add_edge(u,v,e),add_edge(v,u,e); 138 dfs1(1),dfs2(1,1); 139 for(int i=1;i<n;++i) val[dfn[num[i]]]=edge[i<<1]; 140 build(1,1,n); 141 char s[10];int u,v,x; 142 while(true){ 143 scanf("%s",s+1);if(s[1]=='S') break; 144 switch(s[2]){ 145 case 'h':u=read(),x=read(),Change(u,x);break; 146 case 'o':u=read(),v=read(),x=read(),Cover(u,v,x);break; 147 case 'd':u=read(),v=read(),x=read(),Add(u,v,x);break; 148 case 'a':u=read(),v=read(),print(get(u,v));break; 149 } 150 } 151 Ot(); 152 return 0; 153 }