[BZOJ1984]月下“毛景树”(树链剖分)
来源:互联网 发布:农业银行软件开发待遇 编辑:程序博客网 时间:2024/05/31 13:14
题目描述
传送门
题解
一眼链剖。
加法标记和覆盖标记不能同时出现。
add加到了cover标记上,cover+=add,add=0;
cover加到了add标记上,add=0,cover=val;
其他照旧。
代码
#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int max_n=5e5+5;const int max_e=max_n*2;const int max_tree=max_n*4;const int MININF=-2147483647;int n,m,x,y,z,u,t,k,w,N,ans;int tot,point[max_n],next[max_e],v[max_e],c[max_e];int father[max_n],son[max_n],faedge[max_n],sonedge[max_n],h[max_n],size[max_n];int top[max_n],num[max_n],val[max_n];int maxn[max_tree],cover[max_tree],add[max_tree];char opt[10];inline void addedge(int x,int y,int z){ ++tot; next[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z; ++tot; next[tot]=point[y]; point[y]=tot; v[tot]=x; c[tot]=z;}inline void dfs_1(int x,int fa,int dep){ size[x]=1; h[x]=dep; father[x]=fa; int maxson=0; for (int i=point[x];i;i=next[i]) if (v[i]!=fa){ faedge[v[i]]=i; dfs_1(v[i],x,dep+1); size[x]+=size[v[i]]; if (size[v[i]]>maxson){ maxson=size[v[i]]; son[x]=v[i]; sonedge[x]=i; } } }inline void dfs_2(int x,int fa){ if (son[fa]!=x) top[x]=x; else top[x]=top[fa]; if (son[x]){ num[sonedge[x]]=++N; val[N]=c[sonedge[x]]; dfs_2(son[x],x); } for (int i=point[x];i;i=next[i]) if (v[i]!=fa&&v[i]!=son[x]){ num[i]=++N; val[N]=c[i]; dfs_2(v[i],x); }}inline void update(int now){ maxn[now]=max(maxn[now<<1],maxn[now<<1|1]); }inline void pushdown(int now,int l,int r,int mid){ if (cover[now]!=-1){ add[now<<1]=add[now<<1|1]=0; maxn[now<<1]=cover[now]; cover[now<<1]=cover[now]; maxn[now<<1|1]=cover[now]; cover[now<<1|1]=cover[now]; cover[now]=-1; } if (add[now]){ maxn[now<<1]+=add[now]; if (cover[now<<1]!=-1) cover[now<<1]+=add[now]; else add[now<<1]+=add[now]; maxn[now<<1|1]+=add[now]; if (cover[now<<1|1]!=-1) cover[now<<1|1]+=add[now]; else add[now<<1|1]+=add[now]; add[now]=0; }}inline void build(int now,int l,int r){ int mid=(l+r)>>1; cover[now]=-1; add[now]=0; if (l==r){ maxn[now]=val[l]; return; } build(now<<1,l,mid); build(now<<1|1,mid+1,r); update(now);}inline void point_change(int now,int l,int r,int x,int v){ int mid=(l+r)>>1; if (l==r){ maxn[now]=v; return; } pushdown(now,l,r,mid); if (x<=mid) point_change(now<<1,l,mid,x,v); else point_change(now<<1|1,mid+1,r,x,v); update(now);}inline void interval_change(int now,int l,int r,int lrange,int rrange,int v,int opt){ int mid=(l+r)>>1; if (lrange<=l&&r<=rrange){ if (opt==0){ maxn[now]=v; cover[now]=v; if (add[now]) add[now]=0; } else{ maxn[now]+=v; if (cover[now]!=-1) cover[now]+=v; else add[now]+=v; } return; } pushdown(now,l,r,mid); if (lrange<=mid) interval_change(now<<1,l,mid,lrange,rrange,v,opt); if (mid+1<=rrange) interval_change(now<<1|1,mid+1,r,lrange,rrange,v,opt); update(now);}inline int query(int now,int l,int r,int lrange,int rrange){ int mid=(l+r)>>1,ans=MININF; if (lrange<=l&&r<=rrange) return maxn[now]; pushdown(now,l,r,mid); if (lrange<=mid) ans=max(ans,query(now<<1,l,mid,lrange,rrange)); if (mid+1<=rrange) ans=max(ans,query(now<<1|1,mid+1,r,lrange,rrange)); return ans;}inline void Change(int u,int t,int w,int opt){ int f1=top[u],f2=top[t]; while (f1!=f2){ if (h[f1]<h[f2]){ swap(u,t); swap(f1,f2); } interval_change(1,1,N,num[faedge[f1]],num[faedge[u]],w,opt); u=father[f1]; f1=top[u]; } if (u==t) return; if (h[u]>h[t]) swap(u,t); interval_change(1,1,N,num[sonedge[u]],num[faedge[t]],w,opt);}inline int Query(int u,int t){ int ans=MININF; int f1=top[u],f2=top[t]; while (f1!=f2){ if (h[f1]<h[f2]){ swap(u,t); swap(f1,f2); } if (num[faedge[f1]]==0&&num[faedge[u]]==0) cout<<u<<"!"<<t<<endl; ans=max(ans,query(1,1,N,num[faedge[f1]],num[faedge[u]])); u=father[f1]; f1=top[u]; } if (u==t) return ans; if (h[u]>h[t]) swap(u,t); if (num[sonedge[u]]==0&&num[faedge[t]]==0) cout<<u<<" "<<t<<endl; ans=max(ans,query(1,1,N,num[sonedge[u]],num[faedge[t]])); return ans;}int main(){ scanf("%d",&n); for (int i=1;i<n;++i){ scanf("%d%d%d",&x,&y,&z); addedge(x,y,z); } dfs_1(1,0,1); dfs_2(1,0); build(1,1,N); while (~scanf("%s",opt)){ if (opt[0]=='S') return 0; switch(opt[1]){ case 'h':{ scanf("%d%d",&k,&w); if (num[2*k-1]) point_change(1,1,N,num[2*k-1],w); else point_change(1,1,N,num[2*k],w); break; } case 'o':{ scanf("%d%d%d",&u,&t,&w); if (u==t) continue; Change(u,t,w,0); break; } case 'd':{ scanf("%d%d%d",&u,&t,&w); if (u==t) continue; Change(u,t,w,1); break; } case 'a':{ scanf("%d%d",&u,&t); ans=Query(u,t); printf("%d\n",ans); break; } } }}
总结
我可以说脏话吗?
好吧我不说脏话。
被鬼畜的错误卡一晚上,什么错误?fye:“数组开小了吧”
1、她不知道我怎么做的2、她没看我代码3、她说她瞎说的别理她4、我开大数组就过了= =
orz fye*
但是我现在还是不知道为什么数组开小罗= =
知道了之后补上。
数组能开多大就开多大。——by iwtwioi
0 0
- [BZOJ1984]月下“毛景树”(树链剖分)
- 【BZOJ1984】月下“毛景树”-树链剖分
- [bzoj1984]月下“毛景树” 树链剖分
- 【bzoj1984】【坑】月下“毛景树” 树链剖分
- bzoj1984 月下“毛景树”树链剖分 线段树
- bzoj1984 月下“毛景树”(边权的树链剖分)
- BZOJ1984月下“毛景树”
- BZOJ1984: 月下“毛景树”
- BZOJ1984: 月下“毛景树”
- BZOJ1984 月下“毛景树”
- bzoj1984 月下“毛景树”
- BZOJ1984——月下“毛景树”
- BZOJ 1984 月下“毛景树” 树链剖分
- 月下“毛景树”
- bzoj 1984: 月下“毛景树” 线段树+树链剖分
- 1984: 月下“毛景树”
- bzoj 1984: 月下“毛景树”
- 月下
- eclipse下修改tomcat的URIEncoding为UTF-8
- C语言实现由PID获取进程名&由进程名获取PID
- 构建 Docker registry 私有镜像,解决docker私有仓库push出错问题
- Xcode的每个版本发布时间
- 单链队列的基本操作实现
- [BZOJ1984]月下“毛景树”(树链剖分)
- 棋盘问题
- Android SQLite如何判断表是否存在
- 阿里云服务器映射到本地磁盘
- C语言-位运算
- The hunt(狩猎)影评
- 【9-3】迭代dict的value
- 2013 带分数
- html不可不知的15条编码原则