[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序上的树状数组维护子树和.查询时累加整块 ...
随机推荐
- python学习笔记(二)之python简单实践
1 安装python开发环境 Linux环境下自动安装好了python,可以通过以下命令更新到python最新版本. #echo "alias python=/usr/bin/python3 ...
- HDU 1002 A + B Problem II (大数加法)
题目链接 Problem Description I have a very simple problem for you. Given two integers A and B, your job ...
- python作业三级菜单day1(第一周)
一.作业需求: 1. 运行程序输出第一级菜单 2. 选择一级菜单某项,输出二级菜单,同理输出三级菜单 3. 菜单数据保存在文件中 4. 让用户选择是否要退出 5. 有返回上一级菜单的功能 二三级菜单文 ...
- 变量对象vs活动对象
这是我见过描述的最为详尽的关于变量对象.活动对象以及闭包的解析,来自知乎,感谢答主: 作者:闭家锁链接:https://www.zhihu.com/question/36393048/answer/7 ...
- js中字符串的操作
1.length 获取字符串长度 var str = "hello world"; alert(str); 2.索引 通过下标获取字符串指定位置的字符,但是不能改变该索引对应的值 ...
- 盲注脚本2.基于bool
盲注脚本2.基于bool #!/usr/bin/env python #encoding:utf-8 #by i3ekr #using # python sqlinject.py -D "数 ...
- Mongo 配置文件 [www]
Mongo 配置文件 [www] http://blog.chinaunix.net/uid-25206403-id-3510934.html mongodb 安装使用 http://blog.si ...
- 让我们来一起学习OC吧
在本分类中的接下来的将翻译http://rypress.com/tutorials/objective-c/index 通过每一章节的翻译,使得自己的OC基础扎实并分享给大家.
- 字符串截取,SubString
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAk8AAACYCAIAAAByAZqHAAAYgklEQVR4nO2dL28ku5qHTS4ctuTSQf ...
- 《深入浅出MyBatis技术原理与实战》——6. MyBatis的解析和运行原理
MyBatis的运行分为两大部分,第一部分是读取配置文件缓存到Configuration对象,用以创建SqlSessionFactory,第二部分是SqlSession的执行过程. 6.1 涉及的技术 ...