【codevs2460】【BZOJ1036】树的统计count,第一次的树链剖分
来源:互联网 发布:马丁靴 知乎 编辑:程序博客网 时间:2024/06/05 23:43
传送门1
传送门2
写在前面:昨天一个小时能A三道题,今天三个小时A一道题
思路:比较裸的树链剖分,只不过是把边权值变成了点权值,开一个数组记录边和点的关系
注意:
1.比较最大值时ans设为-∞,不要设成0!
2.据本人经验,一个结构体有助于身体健康,两个就不行了……
代码:
#include<bits/stdc++.h>#define mul(x) (x<<1)#define Minn -0x7fffffffusing namespace std;int n,q,tot,x,y,cnt;int first[30010],pre[30010];char ch[10];struct point{ int top,siz,dep,fa,son,w,hash;}a[30010];struct os{ int u,v,next;}e[60010];struct node{ int sum,maxn;}tree[120010];void add(int x,int y){ e[++tot].u=x; e[tot].v=y; e[tot].next=first[x]; first[x]=tot;}void dfs1(int now){ a[now].siz=1; for (int i=first[now];i;i=e[i].next) if (e[i].v!=a[now].fa) { a[e[i].v].fa=now; a[e[i].v].dep=a[now].dep+1; dfs1(e[i].v); if (a[e[i].v].siz>a[a[now].son].siz) a[now].son=e[i].v; a[now].siz+=a[e[i].v].siz; }}void dfs2(int now,int tp){ a[now].hash=++cnt; a[now].top=tp; pre[cnt]=now; if (a[now].son) dfs2(a[now].son,tp); for (int i=first[now];i;i=e[i].next) if (e[i].v!=a[now].son&&e[i].v!=a[now].fa) dfs2(e[i].v,e[i].v);}void build(int now,int begin,int end){ if (begin==end) {tree[now].sum=tree[now].maxn=a[pre[begin]].w;return;} int mid=(begin+end)>>1; build(mul(now),begin,mid); build(1+mul(now),mid+1,end); tree[now].maxn=max(tree[mul(now)].maxn,tree[1+mul(now)].maxn); tree[now].sum=tree[mul(now)].sum+tree[1+mul(now)].sum;}void update(int now,int begin,int end,int pos,int num){ if (begin==end) {tree[now].sum=tree[now].maxn=num;return;} int mid=(begin+end)>>1; if (pos<=mid) update(mul(now),begin,mid,pos,num); else update(1+mul(now),mid+1,end,pos,num); tree[now].maxn=max(tree[mul(now)].maxn,tree[1+mul(now)].maxn); tree[now].sum=tree[mul(now)].sum+tree[1+mul(now)].sum;}int get_max(int now,int begin,int end,int l,int r){ if (l<=begin&&end<=r) return tree[now].maxn; int mid=(begin+end)>>1,ans=Minn; if (l<=mid) ans=max(ans,get_max(mul(now),begin,mid,l,r)); if (r>mid) ans=max(ans,get_max(mul(now)+1,mid+1,end,l,r)); return ans;}int get_sum(int now,int begin,int end,int l,int r){ if (l<=begin&&end<=r) return tree[now].sum; int mid=(begin+end)>>1,ans=0; if (l<=mid) ans+=get_sum(mul(now),begin,mid,l,r); if (r>mid) ans+=get_sum(mul(now)+1,mid+1,end,l,r); return ans;}int solve1(int l,int r){ int ans=Minn,f1=a[l].top,f2=a[r].top; while (f1!=f2) { if (a[f1].dep<a[f2].dep) swap(f1,f2),swap(l,r); ans=max(ans,get_max(1,1,cnt,a[f1].hash,a[l].hash)); l=a[f1].fa;f1=a[l].top; } if (a[l].dep>a[r].dep) swap(l,r); return max(ans,get_max(1,1,cnt,a[l].hash,a[r].hash));}int solve2(int l,int r){ int ans=0,f1=a[l].top,f2=a[r].top; while (f1!=f2) { if (a[f1].dep<a[f2].dep) swap(f1,f2),swap(l,r); ans+=get_sum(1,1,cnt,a[f1].hash,a[l].hash); l=a[f1].fa;f1=a[l].top; } if (a[l].dep>a[r].dep) swap(l,r); return ans+get_sum(1,1,cnt,a[l].hash,a[r].hash);}main(){ scanf("%d",&n); for (int i=1;i<n;i++) scanf("%d%d",&x,&y), add(x,y), add(y,x); for (int i=1;i<=n;i++) scanf("%d",&a[i].w); dfs1(1); dfs2(1,1); build(1,1,cnt); scanf("%d",&q); while (q--) { scanf("%s",ch); scanf("%d%d",&x,&y); if (ch[0]=='C') update(1,1,cnt,a[x].hash,y); else { if (ch[1]=='M') printf("%d\n",solve1(x,y)); else printf("%d\n",solve2(x,y)); } }}
0 0
- 【codevs2460】【BZOJ1036】树的统计count,第一次的树链剖分
- bzoj1036 codevs2460: [ZJOI2008]树的统计 树链剖分
- 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 树的统计Count 树链剖分
- BZOJ1036 树的统计Count
- bzoj1036树的统计Count
- BZOJ1036树的统计Count
- bzoj1036 树的统计Count
- [Bzoj1036][ZJOI2008]树的统计Count
- codeforces-148A-Insomnia cure
- 利用Wireshark分析TCP三次握手
- 背包问题(背包九讲)
- 九度题目1163素数
- JAVA学习第三集:数组与流式程序
- 【codevs2460】【BZOJ1036】树的统计count,第一次的树链剖分
- Codeforces 405 E. Graph Cutting ( DFS )
- Java Base
- .NET全栈开发工程师学习路径
- ListView中Item与Button、CheckBox冲突
- POJ 2386 Lake Counting(简单的深度搜索)
- Class.getResource()、ClassLoader.getResource()和this.class.getClassLoader()解析
- Android源代码
- C++标准模板库