bzoj 3531(树链剖分)
来源:互联网 发布:马蓉面相 知乎 编辑:程序博客网 时间:2024/06/03 12:39
传送门
每个宗教维护一棵线段树,要动态开点,否则可能会爆空间,数组到底开多少本蒟蒻也不清楚,反正稍微开大点,对于此题的空间如果动态开还是可以稍微多开一点的,其余的就是链剖模板了。
注意:在update时不仅要更新线段树,原来的数组a[],c[](宗教、评级)也要修改!
#include<bits/stdc++.h>#define lson lc[rt],l,mid#define rson rc[rt],mid+1,rusing namespace std;const int maxn=1e5+2,MN=5e6+2;int n,m,a[maxn],c[maxn];int head[maxn],edge=0,tim=0;struct EDGE { int v,nxt;}e[maxn<<1];int mx[MN],sum[MN],lc[MN],rc[MN],root[maxn];int fa[maxn],dep[maxn],siz[maxn],top[maxn],rk[maxn],tid[maxn],son[maxn];inline int read() { int x=0;char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); return x;}inline void adde(int u,int v) { e[edge].v=v,e[edge].nxt=head[u],head[u]=edge++; e[edge].v=u,e[edge].nxt=head[v],head[v]=edge++;}void dfs1(int p,int father) { fa[p]=father,dep[p]=dep[fa[p]]+1,siz[p]=1; for (int i=head[p];~i;i=e[i].nxt) { int v=e[i].v; if (v==fa[p]) continue; dfs1(v,p); siz[p]+=siz[v]; if (son[p]==-1||siz[son[p]]<siz[v]) son[p]=v; }}void dfs2(int p,int tp) { top[p]=tp,tid[p]=++tim,rk[tid[p]]=p; if (son[p]==-1) return ; dfs2(son[p],tp); for (int i=head[p];~i;i=e[i].nxt) { int v=e[i].v; if (v!=fa[p]&&v!=son[p]) dfs2(v,v); }}inline void pushup(int rt) { mx[rt]=max(mx[lc[rt]],mx[rc[rt]]); sum[rt]=sum[lc[rt]]+sum[rc[rt]];}void update(int &rt,int l,int r,int pos,int val) { if (!rt) rt=++tim; if (l==r) { mx[rt]=sum[rt]=val; return ; } int mid=(l+r)>>1; if (pos<=mid) update(lson,pos,val); else update(rson,pos,val); pushup(rt);}int qsum(int rt,int l,int r,int L,int R) { if (L<=l&&r<=R) return sum[rt]; int mid=(l+r)>>1,ans=0; if (L<=mid) ans+=qsum(lson,L,R); if (mid<R) ans+=qsum(rson,L,R); return ans;}int qmax(int rt,int l,int r,int L,int R) { if (L<=l&&r<=R) return mx[rt]; int mid=(l+r)>>1,ans=0; if (L<=mid) ans=max(ans,qmax(lson,L,R)); if (mid<R) ans=max(ans,qmax(rson,L,R)); return ans;}int get_sum(int x,int y) { int res=0,cc=c[x]; while (top[x]^top[y]) { if (dep[top[x]]<dep[top[y]]) x^=y^=x^=y; res+=qsum(root[cc],1,n,tid[top[x]],tid[x]); x=fa[top[x]]; } if (dep[x]>dep[y]) x^=y^=x^=y; res+=qsum(root[cc],1,n,tid[x],tid[y]); return res;}int get_max(int x,int y) { int res=0,cc=c[x]; while (top[x]^top[y]) { if (dep[top[x]]<dep[top[y]]) x^=y^=x^=y; res=max(res,qmax(root[cc],1,n,tid[top[x]],tid[x])); x=fa[top[x]]; } if (dep[x]>dep[y]) x^=y^=x^=y; res=max(res,qmax(root[cc],1,n,tid[x],tid[y])); return res;}int main() {// freopen("bzoj 3531.in","r",stdin); memset(mx,0,sizeof(mx)), memset(sum,0,sizeof(sum)), memset(root,0,sizeof(root)), memset(lc,0,sizeof(lc)), memset(rc,0,sizeof(rc)), memset(head,-1,sizeof(head)), memset(son,-1,sizeof(son)), n=read(),m=read(); for (register int i=1;i<=n;++i) a[i]=read(),c[i]=read(); for (register int i=1;i<n;++i) { int u=read(),v=read(); adde(u,v); } dfs1(1,1); dfs2(1,1),tim=0;//tim would be used again in the segtree for (register int i=1;i<=n;++i) update(root[c[i]],1,n,tid[i],a[i]); while (m--) { char ss[5]; scanf("%s",ss); if (!strcmp(ss,"CC")) { int pos=read(),val=read(); update(root[c[pos]],1,n,tid[pos],0); c[pos]=val; update(root[c[pos]],1,n,tid[pos],a[pos]); } else if (!strcmp(ss,"CW")) { int pos=read(),val=read(); update(root[c[pos]],1,n,tid[pos],a[pos]=val); } else if (!strcmp(ss,"QS")) { int s=read(),t=read(); printf("%d\n",get_sum(s,t)); } else { int s=read(),t=read(); printf("%d\n",get_max(s,t)); } } return 0;}
阅读全文
0 0
- bzoj 3531(树链剖分)
- 【bzoj 3531】 [Sdoi2014]旅行(树链剖分+树套树)
- BZOJ 3531 旅行【树链剖分】
- bzoj 1036(树链剖分)
- bzoj 4034(树链剖分)
- BZOJ 3531 SDOI2014 旅行 树链剖分
- bzoj 3531: [Sdoi2014]旅行 树链剖分
- BZOJ 3531 [Sdoi2014]旅行 树链剖分
- 树链剖分+动态线段树(BZOJ-3531旅行)
- BZOJ 3531 (树链剖分,线段树动态开点)
- [树链剖分 线段树] BZOJ 3531 [Sdoi2014]旅行
- bzoj 3531(动态加点线段树,树链剖分)
- BZOJ 3531 [SDOI2014]旅行 树链剖分+线段树
- bzoj 3531: [Sdoi2014]旅行 线段树+树链剖分
- BZOJ 3531 [Sdoi2014]旅行 树链剖分 线段树
- BZOJ 2819 Nim (树链剖分+线段树)
- BZOJ 2243 染色(树链剖分+线段树)
- bzoj 4127: Abs(树链剖分+线段树)
- 剑客决斗(flag)
- shiro学习(一)
- nopCommerce 3.9 大波浪系列 之 路由扩展 [多语言Seo的实现]
- 学习Cocos的一些链接
- windows可视化编程(五)
- bzoj 3531(树链剖分)
- CentOS配置samba服务
- Zookeeper_的特性
- 二叉树的递归与非递归遍历(前序、中序、后序)
- 计算机网络概述
- java map接口
- ProtoBuffer 描述规则
- JDBC:java数据库连接
- 二:撤销(工作区)修改