[BZOJ4765]普通计算姬(分块+树状数组)
4765: 普通计算姬
Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 1725 Solved: 376
[Submit][Status][Discuss]Description
"奋战三星期,造台计算机"。小G响应号召,花了三小时造了台普通计算姬。普通计算姬比普通计算机要厉害一些。普通计算机能计算数列区间和,而普通计算姬能计算树中子树和。更具体地,小G的计算姬可以解决这么个问题:给定一棵n个节点的带权树,节点编号为1到n,以root为根,设sum[p]表示以点p为根的这棵子树中所有节点的权值和。计算姬支持下列两种操作:1 给定两个整数u,v,修改点u的权值为v。2 给定两个整数l,r,计算sum[l]+sum[l+1]+....+sum[r-1]+sum[r]尽管计算姬可以很快完成这个问题,可是小G并不知道它的答案是否正确,你能帮助他吗?Input
第一行两个整数n,m,表示树的节点数与操作次数。接下来一行n个整数,第i个整数di表示点i的初始权值。接下来n行每行两个整数ai,bi,表示一条树上的边,若ai=0则说明bi是根。接下来m行每行三个整数,第一个整数op表示操作类型。若op=1则接下来两个整数u,v表示将点u的权值修改为v。若op=2则接下来两个整数l,r表示询问。N<=10^5,M<=10^50<=Di,V<2^31,1<=L<=R<=N,1<=U<=NOutput
对每个操作类型2输出一行一个整数表示答案。Sample Input
6 4
0 0 3 4 0 1
0 1
1 2
2 3
2 4
3 5
5 6
2 1 2
1 1 1
2 3 6
2 3 5Sample Output
16
10
9HINT
Source
因为每个点的编号都是给定的,所以任何基于连续序列的数据结构(如DFS序等)都会失效(听说KDT可做),于是分块。
然后分块也是有讲究的,这题用到了一个套路:f[i][j]表示节点i到根的路径上的有多少个点在第j块中(也就是修改i节点对第j块的贡献),这个直接DFS预处理出来即可。
这样我们整块直接使用f数组,两端暴力上DFS序+树状数组即可。
友情提醒:这题爆long long 。
#include<cmath>
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
#define For(i,x) for (int i=h[x],k; i; i=nxt[i])
typedef unsigned long long ll;
using namespace std; const int N=;
int n,m,bl,B,u,v,l,r,cnt,tim,op,rt;
int h[N],a[N],bel[N],nxt[N<<],L[N],R[N],to[N<<],f[N][];
ll c[N],sm[],s[N],ans;
void ins(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } void add(int x,ll k){ for (; x<=n; x+=x&-x) c[x]+=k; }
ll que(int x){ ll res=; for (; x; x-=x&-x) res+=c[x]; return res; } void dfs(int x,int fa){
rep(i,,B) f[x][i]=f[fa][i];
f[x][bel[x]]++; L[x]=++tim; s[x]=a[x];
For(i,x) if ((k=to[i])!=fa) dfs(k,x),s[x]+=s[k];
R[x]=tim;
} int main(){
freopen("bzoj4765.in","r",stdin);
freopen("bzoj4765.out","w",stdout);
scanf("%d%d",&n,&m); bl=(int)sqrt(n); B=(n-)/bl+;
rep(i,,n) scanf("%d",&a[i]),bel[i]=(i-)/bl+;
rep(i,,n){
scanf("%d%d",&u,&v);
if (u==) rt=v; else ins(u,v),ins(v,u);
}
dfs(rt,); rep(i,,n) sm[bel[i]]+=s[i],add(L[i],a[i]);
rep(i,,m){
scanf("%d",&op);
if (op==){
scanf("%d%d",&u,&v); add(L[u],v-a[u]);
rep(i,,B) sm[i]+=1ll*(v-a[u])*f[u][i]; a[u]=v;
}else{
scanf("%d%d",&l,&r); ans=; int x=bel[l],y=bel[r];
if (x==y) rep(i,l,r) ans+=que(R[i])-que(L[i]-);
else{
rep(i,l,x*bl) ans+=que(R[i])-que(L[i]-);
rep(i,(y-)*bl+,r) ans+=que(R[i])-que(L[i]-);
rep(i,x+,y-) ans+=sm[i];
}
printf("%llu\n",ans);
}
}
return ;
}
[BZOJ4765]普通计算姬(分块+树状数组)的更多相关文章
- BZOJ 4765: 普通计算姬 (分块+树状数组)
传送门 解题思路 树上的分块题,,对于修改操作,每次修改只会对他父亲到根这条链上的元素有影响:对于查询操作,每次查询[l,r]内所有元素的子树,所以就考虑dfn序,进标记一次,出标记一次,然后子树就是 ...
- BZOJ 4765: 普通计算姬 [分块 树状数组 DFS序]
传送门 题意: 一棵树,支持单点修改和询问以$[l,r]$为根的子树的权值和的和 只有我这种不会分块的沙茶不会做这道题吗? 说一点总结: 子树和当然上$dfs$序了,询问原序列一段区间所有子树和,对原 ...
- bzoj 4765 普通计算姬(树状数组 + 分块)
http://www.lydsy.com/JudgeOnline/problem.php?id=4765 很nice的一道题啊(可能是因为卡了n久终于做出来了 题意就是给你一棵带点权的有根树,sum( ...
- 【bzoj2141】排队 分块+树状数组
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别, ...
- 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu
https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...
- 【BZOJ 3295】动态逆序对 - 分块+树状数组
题目描述 给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数. 分析:分块+树状数组 (PS:本题的CDQ分治解法见下一篇) 首先将序列分成T块,每一块开一个树状数组,并且先把最初的 ...
- 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...
- 2018.06.30 BZOJ4765: 普通计算姬(dfs序+分块+树状数组)
4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MB Description "奋战三星期,造台计算机".小G响应号召,花了三小时 ...
- BZOJ4765 普通计算姬(分块+树状数组)
对节点按编号分块.设f[i][j]为修改j号点对第i块的影响,计算f[i][]时dfs一遍即可.记录每一整块的sum.修改时对每一块直接更新sum,同时用dfs序上的树状数组维护子树和.查询时累加整块 ...
随机推荐
- UITableView---iOS-Apple苹果官方文档翻译
本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 //转载请注明出处--本文永久链接:http://www.cnblogs.com/C ...
- 【洛谷 P2762】 太空飞行计划问题(最大权闭合图)
题目链接 最大权闭合图模型,参考 具体做法是从源点向每个实验连一条流量为这个实验的报酬的边,从每个实验向这个实验需要的所有器材各连一条流量为\(INF\)的边,再从每个器材向汇点连一条流量为这个器材的 ...
- tornado 学习之GET POST方法 -- (转)
import torndb import tornado.web import tornado.ioloop from tornado.options import define,options,pa ...
- Linux Platform驱动模型(二) _驱动方法【转】
转自:http://www.cnblogs.com/xiaojiang1025/archive/2017/02/06/6367910.html 在Linux设备树语法详解和Linux Platform ...
- Linux内核通知链机制的原理及实现【转】
转自:http://www.cnblogs.com/armlinux/archive/2011/11/11/2396781.html 一.概念: 大多数内核子系统都是相互独立的,因此某个子系统可能对其 ...
- Linux时间子系统之一:clock source(时钟源)【转】
转自:http://blog.csdn.net/droidphone/article/details/7975694 clock source用于为linux内核提供一个时间基线,如果你用linux的 ...
- 110.Balanced Binary Tree---《剑指offer》面试39
题目链接 题目大意:判断一个二叉树是否是平衡二叉树. 法一:dfs.利用求解二叉树的高度延伸,先计算左子树的高度,再计算右子树的高度,然后两者进行比较.o(nlgn).代码如下(耗时4ms): pub ...
- 2015多校第6场 HDU 5358 First One 枚举,双指针
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5358 题意:如题. 解法:观察式子发现,由于log函数的存在,使得这个函数的值域<=34,然后我 ...
- docker配置桥接网络
[root@localhost ~]# cd /etc/sysconfig/network-scripts/ [root@localhost network-scripts]# cp ifcfg-et ...
- Java学习笔记(十三)——通过Netbeans开发环境生成oracle数据库中表的对应hibernate映射文件
[前面的话] 身体慢慢已经快好了,感觉真好,哈哈. 这篇文章要通过Hibernate对数据库进行操作,而Netbeans可以直接通过数据库逆向生成对应的映射文件.基础文章,选择性阅读. [步骤] 1. ...