bzoj1984 月下“毛景树”
2017-09-30 06:56
302 查看
传送门
果然强校出的题都有坑= =
好吧其实是我太弱
都知道化边权为点权了还没发现链上查询和修改时的坑
知道了这个这题就是板子题了= =
CODE:
发这题的题解就是为了提醒自己:一定要随时注意题目中的坑点以及出题人的良♂苦用心!
果然强校出的题都有坑= =
好吧其实是我太弱
都知道化边权为点权了还没发现链上查询和修改时的坑
知道了这个这题就是板子题了= =
CODE:
#include<cstdio> #include<vector> using namespace std; #define N 100005 struct tree { int num,change,plus; }t[N<<2]; int f ,deep ,size ,son ,top ,pos ,s ,point ,num ; char str[10]; int n,m,x,y,z,tot; vector<int> v ,w ,id ; inline int max(const int &a,const int &b){return a>b?a:b;} inline int min(const int &a,const int &b){return a<b?a:b;} inline void swap(int &a,int &b){a^=b,b^=a,a^=b;} inline int read() { int n=0;char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') n=(n<<3)+(n<<1)+c-48,c=getchar(); return n; } inline bool getstring() { char c=getchar();int p=0; while(c<'A'||c>'Z') c=getchar(); str[0]=c,c=getchar(); while(c>='a'&&c<='z') str[++p]=c,c=getchar(); return str[0]!='S'; } void dfs(int now,int fa,int depth) { f[now]=fa,deep[now]=depth; size[now]=1; int tmp=0,top=v[now].size(); for(int i=0,to=v[now][0];i<top;to=v[now][++i]) if(to!=fa) { s[to]=w[now][i],point[id[now][i]]=to; dfs(to,now,depth+1); size[now]+=size[to]; if(size[to]>tmp) tmp=size[to],son[now]=to; } } void dfs2(int now,int high) { top[now]=high,pos[now]=++tot; num[tot]=s[now]; if(son[now]) dfs2(son[now],high); int top=v[now].size(); for(int i=0,to=v[now][0];i<top;to=v[now][++i]) if(to!=f[now]&&to!=son[now]) dfs2(to,to); } inline void pushdown(int now) { if(!t[now].change&&!t[now].plus) return; int s1=now<<1,s2=now<<1|1; if(t[now].change) { t[s1].change=t[s2].change=t[s1].num=t[s2].num=t[now].change; t[s1].plus=t[s2].plus=0; t[now].change=0; } if(t[now].plus) { t[s1].num+=t[now].plus,t[s2].num+=t[now].plus; t[s1].plus+=t[now].plus,t[s2].plus+=t[now].plus; t[now].plus=0; } } inline void update(int now) { t[now].num=max(t[now<<1].num,t[now<<1|1].num); } void build(int l,int r,int now) { if(l==r){t[now].num=num[l];return;} int mid=(l+r)>>1; build(l,mid,now<<1); build(mid+1,r,now<<1|1); update(now); } void add(int L,int R,int l,int r,int now,int num) { if(L<=l&&r<=R){t[now].plus+=num,t[now].num+=num;return;} int mid=(l+r)>>1; pushdown(now); if(L<=mid) add(L,R,l,mid,now<<1,num); if(R>mid) add(L,R,mid+1,r,now<<1|1,num); update(now); } void change(int L,int R,int l,int r,int now,int num) { if(L<=l&&r<=R){t[now].change=t[now].num=num,t[now].plus=0;return;} int mid=(l+r)>>1; pushdown(now); if(L<=mid) change(L,R,l,mid,now<<1,num); if(R>mid) change(L,R,mid+1,r,now<< 10bf1 1|1,num); update(now); } int ask(int L,int R,int l,int r,int now) { if(L<=l&&r<=R) return t[now].num; int mid=(l+r)>>1,ans=0; pushdown(now); if(L<=mid) ans=ask(L,R,l,mid,now<<1); if(R>mid) ans=max(ans,ask(L,R,mid+1,r,now<<1|1)); return ans; } inline void addpath(int x,int y,int z) { for(;top[x]!=top[y];x=f[top[x]]) { if(deep[top[x]]<deep[top[y]]) swap(x,y); add(pos[top[x]],pos[x],1,n,1,z); } if(x==y) return; if(deep[x]>deep[y]) swap(x,y); int tmp=ask(pos[x],pos[x],1,n,1); add(pos[x],pos[y],1,n,1,z); change(pos[x],pos[x],1,n,1,tmp); } inline void changepath(int x,int y,int z) { for(;top[x]!=top[y];x=f[top[x]]) { if(deep[top[x]]<deep[top[y]]) swap(x,y); change(pos[top[x]],pos[x],1,n,1,z); } if(x==y) return; if(deep[x]>deep[y]) swap(x,y); int tmp=ask(pos[x],pos[x],1,n,1); change(pos[x],pos[y],1,n,1,z); change(pos[x],pos[x],1,n,1,tmp); } inline int askpath(int x,int y) { change(1,1,1,n,1,0); int ans=0; for(;top[x]!=top[y];x=f[top[x]]) { if(deep[top[x]]<deep[top[y]]) swap(x,y); ans=max(ans,ask(pos[top[x]],pos[x],1,n,1)); } if(x==y) return ans; if(deep[x]>deep[y]) swap(x,y); int tmp=ask(pos[x],pos[x],1,n,1); change(pos[x],pos[x],1,n,1,0); ans=max(ans,ask(pos[x],pos[y],1,n,1)); change(pos[x],pos[x],1,n,1,tmp); return ans; } int main() { n=read(); for(int i=1;i<n;i++) x=read(),y=read(),z=read(), v[x].push_back(y),v[y].push_back(x), w[x].push_back(z),w[y].push_back(z), id[x].push_back(i),id[y].push_back(i); dfs(1,0,1),dfs2(1,1),build(1,n,1); while(getstring()) { x=read(),y=read(); if(str[1]=='h') change(pos[point[x]],pos[point[x]],1,n,1,y); else if(str[1]=='o') changepath(x,y,read()); else if(str[1]=='d') addpath(x,y,read()); else printf("%d\n",askpath(x,y)); } return 0; }
发这题的题解就是为了提醒自己:一定要随时注意题目中的坑点以及出题人的良♂苦用心!
相关文章推荐
- 【树链剖分】【分块】【最近公共祖先】【块状树】bzoj1984 月下“毛景树”
- [BZOJ1984]月下“毛景树”(树链剖分)
- [BZOJ1984]月下“毛景树”(树链剖分)
- BZOJ[1984]月下“毛景树” 树链剖分+线段树
- 【BZOJ1984】月下“毛景树” 树链剖分+线段树
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
- bzoj1984 月下“毛景树”(边权的树链剖分)
- 【BZOJ-1984】月下“毛景树” 树链剖分
- bzoj 1984: 月下“毛景树” (树链剖分)
- BZOJ1984: 月下“毛景树”
- BZOJ 1984: 月下“毛景树”( 树链剖分 )
- 【BZOJ】1984 月下“毛景树”
- BZOJ1984月下“毛景树”
- BZOJ 1984 月下“毛景树”
- [BZOJ1984] 月下“毛景树”
- 【BZOJ】【P1984】【月下“毛景树”】【题解】【链剖线段树】
- bzoj1984 月下“毛景树”树链剖分 线段树
- [BZOJ1984] 月下“毛景树”|树链剖分|线段树
- bzoj1984 月下“毛景树”
- BZOJ1984: 月下“毛景树”