1. 程式人生 > >2018.10.27 bzoj1984: 月下“毛景樹”(樹鏈剖分)

2018.10.27 bzoj1984: 月下“毛景樹”(樹鏈剖分)

傳送門
唉蒟蒻又退化了,這道sb題居然做了20min,最後發現是 u p d c o v updcov 寫成了 u

p d a d d updadd 我還能說什麼 233 233

就是讓你轉邊權為點權之後,支援樹上路徑覆蓋,單點覆蓋,路徑加,求路徑最大。
直接亂碼一發居然 A A 了?
貼程式碼了(稍微有點長):

#include<bits/stdc++.h>
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
using namespace std; inline int read(){ int ans=0; char ch=getchar(); while(!isdigit(ch))ch=getchar(); while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar(); return ans; } const int N=1e5+5; int n,m,first[N],top[N],dep[N],fa[N],siz[N],hson[N],pred[N],num[N],a[N],cnt=0,tot=0; struct edge{int v,next,w;}e[N<<1]; inline void add(int u,int v,int w){e[++cnt].v=v,e[cnt].w=w,e[cnt].next=first[u],first[u]=cnt;} void dfs1(int p){ siz[p]=1; for(int i=first[p];i;i=e[i].next){ int v=e[i].v; if(v==fa[p])continue; fa[v]=p,dep[v]=dep[p]+1,a[v]=e[i].w,dfs1(v),siz[p]+=siz[v]; if(siz[v]>siz[hson[p]])hson[p]=v; } } void dfs2(int p,int tp){ top[p]=tp,pred[num[p]=++tot]=p; if(!hson[p])return; dfs2(hson[p],tp); for(int i=first[p];i;i=e[i].next){ int v=e[i].v; if(v!=fa[p]&&v!=hson[p])dfs2(v,v); } } struct Node{int l,r,mx,cov,add;}T[N<<2]; inline void pushup(int p){T[p].mx=max(T[lc].mx,T[rc].mx);} inline void pushadd(int p,int v){T[p].mx+=v,T[p].add+=v;} inline void pushcov(int p,int v){T[p].mx=v,T[p].cov=v,T[p].add=0;} inline void pushdown(int p){ if(~T[p].cov)pushcov(lc,T[p].cov),pushcov(rc,T[p].cov),T[p].cov=-1; if(T[p].add)pushadd(lc,T[p].add),pushadd(rc,T[p].add),T[p].add=0; } inline void build(int p,int l,int r){ T[p].l=l,T[p].r=r,T[p].cov=-1; if(l==r){T[p].mx=a[pred[l]];return;} build(lc,l,mid),build(rc,mid+1,r),pushup(p); } inline void updadd(int p,int ql,int qr,int v){ if(ql>T[p].r||qr<T[p].l)return; if(ql<=T[p].l&&T[p].r<=qr)return pushadd(p,v); pushdown(p); if(qr<=mid)updadd(lc,ql,qr,v); else if(ql>mid)updadd(rc,ql,qr,v); else updadd(lc,ql,mid,v),updadd(rc,mid+1,qr,v); pushup(p); } inline void updcov(int p,int ql,int qr,int v){ if(ql>T[p].r||qr<T[p].l)return; if(ql<=T[p].l&&T[p].r<=qr)return pushcov(p,v); pushdown(p); if(qr<=mid)updcov(lc,ql,qr,v); else if(ql>mid)updcov(rc,ql,qr,v); else updcov(lc,ql,mid,v),updcov(rc,mid+1,qr,v); pushup(p); } inline int query(int p,int ql,int qr){ if(ql>T[p].r||qr<T[p].l)return 0; if(ql<=T[p].l&&T[p].r<=qr)return T[p].mx; pushdown(p); if(qr<=mid)return query(lc,ql,qr); if(ql>mid)return query(rc,ql,qr); return max(query(lc,ql,mid),query(rc,mid+1,qr)); } inline void changeadd(int x,int y,int v){ while(top[x]^top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); updadd(1,num[top[x]],num[x],v),x=fa[top[x]]; } if(dep[x]<dep[y])swap(x,y); updadd(1,num[y]+1,num[x],v); } inline void changecov(int x,int y,int v){ while(top[x]^top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); updcov(1,num[top[x]],num[x],v),x=fa[top[x]]; } if(dep[x]<dep[y])swap(x,y); updcov(1,num[y]+1,num[x],v); } inline int ask(int x,int y){ int ret=0; while(top[x]^top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ret=max(ret,query(1,num[top[x]],num[x])),x=fa[top[x]]; } if(dep[x]<dep[y])swap(x,y); return max(ret,query(1,num[y]+1,num[x])); } int main(){ n=read(); for(int u,v,w,i=1;i<n;++i)u=read(),v=read(),w=read(),add(u,v,w),add(v,u,w); dfs1(1),dfs2(1,1),build(1,1,n); char s[10]; while(1){ scanf("%s",s); if(s[0]=='S')break; int x=read(),y=read(); if(s[0]=='M')printf("%d\n",ask(x,y)); if(s[0]=='C'&&s[1]=='o')changecov(x,y,read()); if(s[0]=='A')changeadd(x,y,read()); if(s[0]=='C'&&s[1]=='h'){ int u=e[x*2].v,v=e[x*2-1].v; if(dep[u]>dep[v])swap(u,v); updcov(1,num[v],num[v],y); } } return 0; }