[BZOJ1036][ZJOI2008]树的统计Count(树链剖分)
来源:互联网 发布:java代码实现单例模式 编辑:程序博客网 时间:2024/04/30 03:54
题目:
我是超链接
解析:
树链剖分模板题
•建树过程O(nlogn)
•每次查询经过O(logn)条重链,对于每条重链在线段树上查询复杂度为O(logn);总复杂度为O(mlog^2n)
树链剖分的话:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
#include <cstdio>#include <cstring>#include <iostream>#define N 30000#define MIN -2100000000using namespace std;//w[i]表示点i的权值,size[i]表示以i为根的子树的结点个数,deep[i]表示点i的深度,fa[i]表示点i的父亲,son[i]表示点i的重儿子 int size[N*4],w[N*4],son[N*4],fa[N*4],deep[N*2+5];//top[i]表示点i所在的链的最头上的点,num[i]表示点i在线段树数组中对应的编号,tree[i]表示在线段树数组中编号为i的点在树中对应的点的编号 int top[N*4],num[N*4],tree[N*4],totw=0;int sum[N*4],maxn[N*4];int next[N*2+5],point[N*2+5],v[N*2+5],tot=0;void addline(int x,int y){++tot; next[tot]=point[x]; point[x]=tot; v[tot]=y;++tot; next[tot]=point[y]; point[y]=tot; v[tot]=x;}void dfs_1(int now,int dep,int faa){deep[now]=dep;size[now]=1;fa[now]=faa;int maxx=0,i;for (i=point[now];i;i=next[i]) if (v[i]!=faa) {dfs_1(v[i],dep+1,now);size[now]+=size[v[i]];if (size[v[i]]>maxx){maxx=size[v[i]];son[now]=v[i];} }}void dfs_2(int now,int faa) {if (son[faa]!=now) top[now]=now;else top[now]=top[fa[now]];num[now]=++totw;if (son[now]) //是叶子节点{dfs_2(son[now],now);for (int i=point[now];i;i=next[i]) if (v[i]!=faa&&v[i]!=son[now]) dfs_2(v[i],now);}}void updatasum(int now){sum[now]=sum[now<<1]+sum[(now<<1)+1];}void updatamaxn(int now){maxn[now]=max(maxn[now<<1],maxn[(now<<1)+1]);}void buildsum(int now,int l,int r){if (l==r){sum[now]=w[tree[l]];return;}int mid=(l+r)>>1;buildsum(now<<1,l,mid);buildsum((now<<1)+1,mid+1,r);updatasum(now);}void buildmaxn(int now,int l,int r){if (l==r){maxn[now]=w[tree[l]];return;}int mid=(l+r)>>1;buildmaxn(now<<1,l,mid);buildmaxn((now<<1)+1,mid+1,r);updatamaxn(now);}void changesum(int now,int l,int r,int x,int v){if (l==r){sum[now]=v;return;}int mid=(l+r)>>1;if (x<=mid) changesum(now<<1,l,mid,x,v);else changesum((now<<1)+1,mid+1,r,x,v);updatasum(now);}void changemaxn(int now,int l,int r,int x,int v){if (l==r){maxn[now]=v;return;}int mid=(l+r)>>1;if (x<=mid) changemaxn(now<<1,l,mid,x,v);else changemaxn((now<<1)+1,mid+1,r,x,v);updatamaxn(now);}int qmax(int now,int l,int r,int lrange,int rrange){ if (l>=lrange&&r<=rrange) return maxn[now]; int mid=(l+r)>>1;int ans=MIN; if (mid>=lrange) ans=max(ans,qmax(now<<1,l,mid,lrange,rrange));if (mid<rrange) ans=max(ans,qmax((now<<1)+1,mid+1,r,lrange,rrange));return ans; }int qsum(int now,int l,int r,int lrange,int rrange){ if (l>=lrange&&r<=rrange) return sum[now]; int mid=(l+r)>>1,ans=0; if (mid>=lrange) ans+=qsum(now<<1,l,mid,lrange,rrange);if (mid<rrange) ans+=qsum((now<<1)+1,mid+1,r,lrange,rrange);return ans; }int main(){int i,n,a,b,q,u,v;scanf("%d",&n);for (i=1;i<=n-1;i++){scanf("%d%d",&a,&b);addline(a,b);} for (i=1;i<=n;i++) scanf("%d",&w[i]); dfs_1(1,1,0); dfs_2(1,0); for (i=1;i<=n;i++) tree[num[i]]=i; buildsum(1,1,n); buildmaxn(1,1,n); scanf("%d",&q); for (i=1;i<=q;i++) { char st[10]; scanf("%s%d%d",&st,&u,&v); if (st[0]=='C') { changemaxn(1,1,n,num[u],v);//u点的权值改为v changesum(1,1,n,num[u],v);}else if (st[1]=='M') { int f1=top[u],f2=top[v]; int maxx=MIN;while (f1!=f2) { if (deep[f1]<deep[f2]) swap(u,v); f1=top[u],f2=top[v];//f1比较深 maxx=max(maxx,qmax(1,1,n,num[f1],num[u])); u=fa[f1]; f1=top[u];}if (num[u]<num[v]) swap(u,v);maxx=max(maxx,qmax(1,1,n,num[v],num[u])); printf("%d\n",maxx);//点l到点r的最大值 }else{int f1=top[u],f2=top[v]; int maxx=0;while (f1!=f2) { if (deep[f1]<deep[f2]) swap(u,v); f1=top[u],f2=top[v];//f1比较深 maxx+=qsum(1,1,n,num[f1],num[u]); u=fa[f1]; f1=top[u];}if (num[u]<num[v]) swap(u,v);maxx+=qsum(1,1,n,num[v],num[u]); printf("%d\n",maxx);//点l到点r的最大值 } }}注意:
求最大值的时候最小值要设为负数...........不可以为0...........
0 0
- BZOJ1036 [ZJOI2008]树的统计Count 树链剖分
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
- 【bzoj1036】【树链剖分】【ZJOI2008】树的统计Count
- 【BZOJ1036】【ZJOI2008】【树的统计count】【树链剖分】
- BZOJ1036: [ZJOI2008]树的统计Count (树链剖分)
- bzoj1036: [ZJOI2008]树的统计Count - 树链剖分
- 【树链剖分】[BZOJ1036][ZJOI2008]树的统计Count
- [树链剖分] BZOJ1036: [ZJOI2008]树的统计Count
- [bzoj1036][ZJOI2008]树的统计Count 树链剖分
- 【bzoj1036】【树链剖分】 [ZJOI2008]树的统计Count
- BZOJ1036 [ZJOI2008]树的统计Count(树链剖分)
- [BZOJ1036][ZJOI2008]树的统计Count(树链剖分)
- [BZOJ1036][ZJOI2008]树的统计Count(树链剖分)
- 树链剖分基础模板(BZOJ1036[ZJOI2008]树的统计Count)
- bzoj1036: [ZJOI2008]树的统计Count(树链剖分)
- [bzoj1036]:[ZJOI2008]树的统计Count(树链剖分)
- [BZOJ1036][ZJOI2008]树的统计Count(树链剖分)
- [Bzoj1036][ZJOI2008]树的统计Count
- java中实现多态的机制是什么?
- 微信小程序发布一个月,世界并没有什么不同
- 发现一个比较好的库: com.google.common.base
- AsyncHttp使用的一些坑
- 1012. The Best Rank (25)
- [BZOJ1036][ZJOI2008]树的统计Count(树链剖分)
- Gsonformat
- 1013. Battle Over Cities (25)
- ssm整合的配置文件
- vim配置中的.vimrc文件内容配置,还有两个插件安装效果图
- 1014. Waiting in Line (30)
- 数据结构哈希表
- 1015. Reversible Primes (20)
- 中华人民共和国财政部令第20号——政府采购供应商投诉处理办法