BZOJ4765 普通计算姬(分块+树状数组)
对节点按编号分块。设f[i][j]为修改j号点对第i块的影响,计算f[i][]时dfs一遍即可。记录每一整块的sum。修改时对每一块直接更新sum,同时用dfs序上的树状数组维护子树和。查询时累加整块区间的sum,剩余部分bit上暴力查询。分析一下复杂度。设块大小为k,计算f数组的复杂度为O(n2/k),修改复杂度为O(nm/k+mlogn),查询复杂度O(nm/k+mklogn)。不妨设nm同阶,则k=sqrt(n/logn)时最优,总复杂度O(n·sqrt(nlogn))。然而真的这样的话f空间不够反正直接开sqrt(n)就过了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll unsigned long long
#define N 100010
#define BLOCK 320
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,p[N],dfn[N],size[N],root,t,cnt;
int block,num,L[BLOCK],R[BLOCK],pos[N],f[BLOCK][N];
ll sum[BLOCK],tree[N],a[N];
struct data{int to,nxt;
}edge[N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void add(int k,int x){while (k<=n) tree[k]+=x,k+=k&-k;}
ll query(int k){ll s=;while (k) s+=tree[k],k-=k&-k;return s;}
void calc(int k,int x,int from,int cnt)
{
if (k>=L[x]&&k<=R[x]) cnt++;
f[x][k]=cnt;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from) calc(edge[i].to,x,k,cnt);
}
void dfs(int k,int from)
{
dfn[k]=++cnt;size[k]=;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from) dfs(edge[i].to,k),size[k]+=size[edge[i].to];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4765.in","r",stdin);
freopen("bzoj4765.out","w",stdout);
const char LL[]="%I64u\n";
#else
const char LL[]="%llu\n";
#endif
n=read(),m=read();
for (int i=;i<=n;i++) a[i]=read();
block=sqrt(n);num=(n-)/block+;
for (int i=;i<=num;i++)
{
L[i]=(i-)*block+,R[i]=min(n,i*block);
for (int j=L[i];j<=R[i];j++)
pos[j]=i;
}
for (int i=;i<=n;i++)
{
int x=read(),y=read();
if (!x) root=y;
else addedge(x,y),addedge(y,x);
}
for (int i=;i<=num;i++) calc(root,i,root,);
dfs(root,root);
for (int i=;i<=n;i++) add(dfn[i],a[i]);
for (int i=;i<=n;i++) sum[pos[i]]+=query(dfn[i]+size[i]-)-query(dfn[i]-);
while (m--)
{
int op=read();
if (op==)
{
int x=read(),y=read();
y-=a[x];
add(dfn[x],y);
for (int i=;i<=num;i++) sum[i]+=(ll)f[i][x]*y;
a[x]+=y;
}
else
{
int l=read(),r=read();
ll ans=;
if (pos[l]==pos[r])
{
for (int i=l;i<=r;i++)
ans+=query(dfn[i]+size[i]-)-query(dfn[i]-);
}
else
{
for (int i=pos[l]+;i<pos[r];i++)
ans+=sum[i];
for (int i=l;i<=R[pos[l]];i++)
ans+=query(dfn[i]+size[i]-)-query(dfn[i]-);
for (int i=L[pos[r]];i<=r;i++)
ans+=query(dfn[i]+size[i]-)-query(dfn[i]-);
}
printf(LL,ans);
}
}
return ;
}
BZOJ4765 普通计算姬(分块+树状数组)的更多相关文章
- [BZOJ4765]普通计算姬(分块+树状数组)
4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 1725 Solved: 376[Submit][Status][Discus ...
- 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响应号召,花了三小时 ...
随机推荐
- 成都Uber优步司机奖励政策(2月20日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 天津Uber优步司机奖励政策(12月28日到12月29日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 弹性分布式数据集RDD概述
[Spark]弹性分布式数据集RDD概述 弹性分布数据集RDD RDD(Resilient Distributed Dataset)是Spark的最基本抽象,是对分布式内存的抽象使用,实现了以操作 ...
- 根据wsdl生成服务端代码
场景描述 最近在和一家公司做业务接口对接,由他们那边回调我们这边,对方直接扔过来一个webservice的wsdl文件,让我们按照他们的规范来做webservice服务, 大多数的对接应该是我们创建完 ...
- 「日常训练」Known Notation(ZOJ-3829)
题意与分析 题意是这样的:给一个字符串,字符串中只包含数字和运算符'*'.现在问字符串是不是一个合法的逆波兰式(后缀表达式).已知逆波兰式的空格消除,也就是说123可以看成123也可以看成1和23.如 ...
- Linux命令应用大词典-第28章 硬件管理
28.1 lscpu:显示有关CPU架构的信息 28.2 nproc:显示当前进程可用的CPU数目 28.3 chcpu:配置CPU
- Python字符串格式化符号及转义字符含义(非常全!!!)
字符串格式化符号含义 符号 说明 %c 格式化字符及其 ASCII 码 %s 格式化字符串 %d 格式化整数 %o 格式化无符号八进制数 %x 格式化无符号十六进制数 %X 格式化无符号十六进制数(大 ...
- Leetcode-跳跃游戏
跳跃游戏 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] ...
- 【转】VSstudio中的一些宏
说明 $(RemoteMachine) 设置为“调试”属性页上“远程计算机”属性的值.有关更多信息,请参见更改用于 C/C++ 调试配置的项目设置. $(References) 以分号分隔的引用列表被 ...
- 【RL系列】Multi-Armed Bandit笔记——UCB策略与Gradient策略
本篇主要是为了记录UCB策略与Gradient策略在解决Multi-Armed Bandit问题时的实现方法,涉及理论部分较少,所以请先阅读Reinforcement Learning: An Int ...