bzoj 1036 [ZJOI2008] 树的统计 树链剖分模板题
来源:互联网 发布:知乎周刊在哪里看 编辑:程序博客网 时间:2024/06/10 16:57
1036: [ZJOI2008]树的统计Count
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 4465 Solved: 1858
[Submit][Status]
Description
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
Input
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
Sample Output
4
1
2
2
10
6
5
6
5
16
又是找不出错误的时候。。。
参考http://blog.csdn.net/jiangshibiao/article/details/24669751
#include<algorithm>#include<vector>#include<cstring>#include<string>#include<iomanip>#include<cstdio>#include<stack>#include<iostream>#include<map>#include<queue>#include<set>#include<cmath>#include<strstream>using namespace std;#define sf scanf#define pf printf#define mem(a,b) memset(a,b,sizeof(a));#define rep(i,a,b) for(int i=(a);i<=(b);++i)#define MP make_pair#define mod 998244353#define ULL unsigned long long#define LL long long#define inf 0x3f3f3f3f#define md ((ll+rr)>>1)#define ls (i<<1)#define rs (ls|1)#define N 5010#define M 20020//2017年08月23日08:36:16int fst[N],nxt[M],to[M],e,val[N],w[N];int fa[N],dep[N],sz[N],son[N];int tid[N],top[N];int sum[N];bool vis[N];int label,n;int mx[N<<2];void init(){ mem(fst,-1); e=0;}void add(int u,int v){ to[e]=v,nxt[e]=fst[u];fst[u]=e++;}void dfs(int u,int p){ fa[u]=p; sz[u]=1; for(int i=fst[u];~i;i=nxt[i]){ int v=to[i]; if(v==p)continue; dep[v]=dep[u]+1; dfs(v,u); sz[u]+=sz[v]; if(sz[son[u]]<sz[v]){ son[u]=sz[v]; } }}void dfs2(int u,int t){ vis[u]=1; top[u]=t; tid[u]=++label; w[label]=val[u]; if(son[u])dfs2(son[u],t); puts("bad"); for(int i=fst[u];~i;i=nxt[i]){ int v=to[i]; puts("bad"); if(!vis[v])dfs2(v,v); }}void cut(){ dep[1]=sz[1]=0; mem(son,0); dfs(1,-1); mem(vis,0); label=0; dfs2(1,1);}void build(int ll,int rr,int i){ if(ll==rr){ mx[i]=w[ll]; sum[i]=w[ll]; return; } build(ll,md,ls),build(md+1,rr,rs); mx[i]=max(mx[ls],mx[rs]); sum[i]=sum[ls]+sum[rs];}void update(int x,int v,int ll,int rr,int i){ if(ll==rr){ sum[i]=v; mx[i]=v;return ; } if(x<=md)update(x,v,ll,md,ls); else update(x,v,md+1,rr,rs); mx[i]=max(mx[ls],mx[rs]); sum[i]=sum[ls]+sum[rs];}int qmax(int l,int r,int ll,int rr,int i){ if(ll==l&&rr==r)return mx[i]; if(r<=md) return qmax(l,r,ll,md,ls); if(l>md) return qmax(l,r,md+1,rr,rs); return max(qmax(l,md,ll,md,ls),qmax(md+1,r,md+1,rr,rs));}int qsum(int l,int r,int ll,int rr,int i){ if(ll==l&&rr==r)return sum[i]; if(r<=md) return qsum(l,r,ll,md,ls); if(l>md) return qsum(l,r,md+1,rr,rs); return qsum(l,md,ll,md,ls)+qsum(md+1,r,md+1,r,rs);}int calmax(int x,int y){ int ret=-inf; while(top[x]!=top[y]){ if(dep[top[x]]>dep[top[y]])swap(x,y); ret=max(ret,qmax(tid[top[y]],tid[y],1,n,1)); y=fa[top[y]]; } if(x!=y){ if(dep[x]>dep[y])swap(x,y); ret=max(ret,qmax(tid[x]+1,tid[y],1,n,1)); } return ret;}int calsum(int x,int y){ int ret=0; while(top[x]!=top[y]){ if(dep[top[x]]>dep[top[y]])swap(x,y); ret+=(qsum(tid[top[y]],tid[y],1,n,1)); y=fa[top[y]]; } if(x!=y){ if(dep[x]>dep[y])swap(x,y); ret+=(qsum(tid[top[y]],tid[y],1,n,1)); } return ret;}int main(){ freopen("in.txt","r",stdin); sf("%d",&n); init(); for(int i=1;i<=n-1;++i){ int u,v;sf("%d%d",&u,&v); add(u,v);add(v,u); } rep(i,1,n)sf("%d",&val[i]); cut(); for(int i=1;i<=n;++i){ pf("%d ",mx[i]); }puts(""); build(1,n,1); int m;sf("%d",&m); while(m--){ char s[10];sf("%s",s); if(s[0]=='C'){ int x,val;sf("%d%d",&x,&val); update(x,val,1,n,1); } else if(s[1]=='S'){ int u,v;sf("%d%d",&u,&v); pf("%d\n",calsum(tid[u],tid[v])); } else if(s[1]=='M'){ int u,v;sf("%d%d",&u,&v); pf("%d\n",calmax(tid[u],tid[v])); } }}
- bzoj 1036 [ZJOI2008] 树的统计 树链剖分模板题
- BZoj 1036: [ZJOI2008]树的统计Count【树链剖分+线段树--模板题】
- BZOJ 1036 [ZJOI2008]树的统计Count 树链剖分练手题
- BZOJ 1036 [ZJOI2008] 数的统计 树链剖分
- BZOJ 1036: [ZJOI2008]树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count
- 【BZOJ 1036】[ZJOI2008]树的统计Count
- bzoj 1036: [ZJOI2008]树的统计Count
- BZOJ 1036 [ZJOI2008]树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count
- BZOJ 1036 [ZJOI2008]树的统计Count
- bzoj 1036 [ZJOI2008]树的统计Count
- 【bzoj】1036: [ZJOI2008]树的统计Count
- [BZOJ]1036: [ZJOI2008]树的统计Count
- BZOJ 1036 [ZJOI2008] 树的统计Count
- 【BZOJ 1036】 [ZJOI2008]树的统计
- BZOJ 1036: [ZJOI2008]树的统计Count
- BZOJ 1036 [ZJOI2008]树的统计Count
- 前端学习(十三)CSS margin的使用
- PAT basic 1069
- 3373-数据结构实验之查找一:二叉排序树
- U盘其它用途
- 通过eslint统一前端IDE的编码风格,避免git冲突
- bzoj 1036 [ZJOI2008] 树的统计 树链剖分模板题
- 使用fiddler抓包保存jmeter文件
- HDU
- Linux--java jdk安装(tar.gz)
- mac 下 android studio 的离线gradle极速配置方法
- Bitmap算法
- thinphp5数据库操作(一)
- Java
- fragment