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^5
0<=Di,V<2^31,1<=L<=R<=N,1<=U<=N

Output

对每个操作类型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 5

Sample Output

16
10
9

HINT

Source

[Submit][Status][Discuss]

因为每个点的编号都是给定的,所以任何基于连续序列的数据结构(如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]普通计算姬(分块+树状数组)的更多相关文章

  1. BZOJ 4765: 普通计算姬 (分块+树状数组)

    传送门 解题思路 树上的分块题,,对于修改操作,每次修改只会对他父亲到根这条链上的元素有影响:对于查询操作,每次查询[l,r]内所有元素的子树,所以就考虑dfn序,进标记一次,出标记一次,然后子树就是 ...

  2. BZOJ 4765: 普通计算姬 [分块 树状数组 DFS序]

    传送门 题意: 一棵树,支持单点修改和询问以$[l,r]$为根的子树的权值和的和 只有我这种不会分块的沙茶不会做这道题吗? 说一点总结: 子树和当然上$dfs$序了,询问原序列一段区间所有子树和,对原 ...

  3. bzoj 4765 普通计算姬(树状数组 + 分块)

    http://www.lydsy.com/JudgeOnline/problem.php?id=4765 很nice的一道题啊(可能是因为卡了n久终于做出来了 题意就是给你一棵带点权的有根树,sum( ...

  4. 【bzoj2141】排队 分块+树状数组

    题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别, ...

  5. 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu

    https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...

  6. 【BZOJ 3295】动态逆序对 - 分块+树状数组

    题目描述 给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数. 分析:分块+树状数组 (PS:本题的CDQ分治解法见下一篇) 首先将序列分成T块,每一块开一个树状数组,并且先把最初的 ...

  7. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  8. 2018.06.30 BZOJ4765: 普通计算姬(dfs序+分块+树状数组)

    4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MB Description "奋战三星期,造台计算机".小G响应号召,花了三小时 ...

  9. BZOJ4765 普通计算姬(分块+树状数组)

    对节点按编号分块.设f[i][j]为修改j号点对第i块的影响,计算f[i][]时dfs一遍即可.记录每一整块的sum.修改时对每一块直接更新sum,同时用dfs序上的树状数组维护子树和.查询时累加整块 ...

随机推荐

  1. COGS1882 [国家集训队2011]单选错位

    ★   输入文件:nt2011_exp.in   输出文件:nt2011_exp.out   简单对比时间限制:1 s   内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题 ...

  2. 【Codeforces】868C. Qualification Rounds

    [题目]C. Qualification Rounds [题意]给定n个问题和K个人,给定每个人知道的问题列表,求能否找到一个非空问题集合,满足每个人知道的集合中问题数量都不超过集合总题数的一半.n& ...

  3. HDU 1422 重温世界杯 (dp)

    题目链接 Problem Description 世界杯结束了,意大利人连本带利的收回了法国人6年前欠他们的债,捧起了大力神杯,成就了4星意大利. 世界杯虽然结束了,但是这界世界杯给我们还是留下许多值 ...

  4. 使用GDB命令行调试器调试C/C++程序【转】

    转自:https://linux.cn/article-4302-1.html 编译自:http://xmodulo.com/gdb-command-line-debugger.html作者: Adr ...

  5. MACACA===gradle下载和安装

    gradle下载地址: http://services.gradle.org/distributions/ 或者直接点击这个: http://services.gradle.org/distribut ...

  6. 004_ssh连接慢的问题的解决?

    <1>群中同学遇到的问题,我之前在uuwatch也遇到了同样的问题? 问个问题师兄们 突然之间 公司服务器连接很慢 连一个shell需要10几秒钟 服务器就在公司全是内网服务器, 我也不知 ...

  7. mui 选项卡与header文字同步

    mui底部tab固定 头部nav可变 <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...

  8. 字符串aaaa......bbbb....ccc...dddddd用正则替换为abcd

    public static void main(String[] args) { String s = "aaaa......bbbb....ccc...dddddd"; Stri ...

  9. mac pro 安装mysql并且配置my.cnf(添加默认字符集utf8,数据存放路径,修改已经建好的表的默认字符集等)、mac mysql my.cnf路径

    如果你是还没有下载安装文件,请到官网下载http://dev.mysql.com/downloads/mysql/ 下载好mysql的mac版本的安装文件后解压后将文件放到目录 /usr/local/ ...

  10. Zookeeper 入门第一篇

    转载原文地址: ZooKeeper学习总结 第一篇:ZooKeeper快速入门 ZooKeeper学习总结 第二篇:ZooKeeper深入探讨 ZooKeeper学习第一期---Zookeeper简单 ...