bzoj 1036 洛谷 p2590 [ZJOI2008]树的统计
来源:互联网 发布:首次适应算法java 编辑:程序博客网 时间:2024/06/07 02:52
题目描述
一棵树上有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本身
输入输出格式
输入格式:
输入文件的第一行为一个整数n,表示节点的个数。
接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。
接下来一行n个整数,第i个整数wi表示节点i的权值。
接下来1行,为一个整数q,表示操作的总数。
接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
输出格式:
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
输入输出样例
输入样例#1:
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
输出样例#1:
4
1
2
2
10
6
5
6
5
16
说明
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#define int long long#define ls id<<1#define rs id<<1|1using namespace std;const int N=100005;int n,m,r,p,tot,dcnt,q;int w[N],head[N*2],mp[N];struct NODE{ int to,nex;}ed[N*2];struct node{ int fa,son,sz,dep,top,s,e;}tr[N];//树链剖分struct Segtree{ int l,r; int sum,lazy,maxx;}tree[4*N];inline void addedge(int x,int y){ ++tot; ed[tot].nex=head[x]; head[x]=tot; ed[tot].to=y;}inline int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();} return f*x;}void dfs1(int u){ tr[u].sz=1; for(int i=head[u];i;i=ed[i].nex) if(ed[i].to!=tr[u].fa){ tr[ed[i].to].fa=u; tr[ed[i].to].dep=tr[u].dep+1; dfs1(ed[i].to); tr[u].sz+=tr[ed[i].to].sz; if(tr[ed[i].to].sz>tr[tr[u].son].sz){ tr[u].son=ed[i].to; } }}void dfs2(int u,int top){ tr[u].top=top; tr[u].s=++dcnt; mp[dcnt]=u; if(tr[u].son){ dfs2(tr[u].son,top); for(int i=head[u];i;i=ed[i].nex) if(ed[i].to!=tr[u].fa&&ed[i].to!=tr[u].son) dfs2(ed[i].to,ed[i].to); } tr[u].e=dcnt;}inline void update(int b){ tree[b].sum=tree[b*2].sum+tree[b*2+1].sum; tree[b].maxx=max(tree[b*2].maxx,tree[b*2+1].maxx);}void build(int b,int l,int r){ tree[b].l=l; tree[b].r=r; if(l==r){ tree[b].sum=tree[b].maxx=w[mp[l]]; return ; } int mid=l+r>>1; build(b*2,l,mid); build(b*2+1,mid+1,r); update(b);}int qsum(int id,int l,int r){ if(tree[id].l>r || tree[id].r<l)return 0; if(tree[id].l>=l && tree[id].r<=r)return tree[id].sum; return (qsum(id*2,l,r)+qsum(id*2+1,l,r));}int qmax(int id,int l,int r){ int ans=-1e9; if(tree[id].l>r || tree[id].r<l)return -1e9; if(tree[id].l>=l && tree[id].r<=r)return max(ans,tree[id].maxx); return max(qmax(id*2,l,r),qmax(id*2+1,l,r));}int query(int x,int y){ int f1=tr[x].top; int f2=tr[y].top; int ans=0; while(f1!=f2){ if(tr[f1].dep<tr[f2].dep){ swap(x,y); swap(f1,f2); } ans+=qsum(1,tr[f1].s,tr[x].s); x=tr[f1].fa; f1=tr[x].top; } if(tr[x].dep>tr[y].dep) swap(x,y); return ans=ans+qsum(1,tr[x].s,tr[y].s);}int find(int x,int y){ int f1=tr[x].top; int f2=tr[y].top; int ans=-10000000; while(f1!=f2){ if(tr[f1].dep<tr[f2].dep){ swap(x,y); swap(f1,f2); } ans=max(ans,qmax(1,tr[f1].s,tr[x].s)); x=tr[f1].fa; f1=tr[x].top; } if(tr[x].dep<tr[y].dep) ans=max(ans,qmax(1,tr[x].s,tr[y].s)); else ans=max(ans,qmax(1,tr[y].s,tr[x].s)); return ans;}void change(int b,int x,int y,int z){ if(y<tree[b].l||x>tree[b].r) return ; if(tree[b].l==tree[b].r){ tree[b].maxx=z; tree[b].sum=z; return ; } change(b*2,x,y,z); change(b*2+1,x,y,z); update(b);}main(){ n=read(); for(int i=1;i<n;i++){ int x,y; x=read(); y=read(); addedge(x,y); addedge(y,x); } for(int i=1;i<=n;i++) w[i]=read(); dfs1(1); dfs2(1,1); build(1,1,n); q=read(); for(int i=1;i<=q;i++){ string mode; int x,y,z; cin>>mode; if(mode=="QSUM") { scanf("%lld%lld",&x,&y); printf("%lld\n",query(x,y)); } else if(mode=="CHANGE") { scanf("%lld%lld",&x,&z); change(1,tr[x].s,tr[x].s,z); } else if(mode=="QMAX") { scanf("%lld%lld",&x,&y); printf("%lld\n",find(x,y)); } } return 0;}
注意这题输入有负数,求ans要搞好初值
阅读全文
0 0
- bzoj 1036 洛谷 p2590 [ZJOI2008]树的统计
- 洛谷P2590 [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
- 【bzoj 1036】 [ZJOI2008]树的统计Count
- BZOJ 1036 [ZJOI2008]树的统计Count
- LWC 53:695. Max Area of Island
- 浅论Maven和Git的原理及展示其与Eclipse的集成
- 全局异常捕获器_多博客摘抄~
- Codeforces Round #439 (Div. 2) B. The Eternal Immortality
- 数据库
- bzoj 1036 洛谷 p2590 [ZJOI2008]树的统计
- 10.8 蜡烛 2403
- 《剑指offer》刷题笔记(代码完整性):数值的整数次方
- javaWeb企业级了解
- C++ const
- 1001. 害死人不偿命的(3n+1)猜想
- HTTP
- 电子工程师必备九大系统电路
- 四点旅行