传送门

题意:

一棵树,支持单点修改和询问以$[l,r]$为根的子树的权值和的和


只有我这种不会分块的沙茶不会做这道题吗?

说一点总结:

子树和当然上$dfs$序了,询问原序列一段区间所有子树和,对原序列分块,$sum_i$为一块的答案

查询很显然了,整块用$sum$,非整块暴力查子树

修改的话,预处理$f[i][j]$为点$j$对第$i$块的贡献,一遍$dfs$就可以预处理出来

然后,我的$BIT$用了$build$函数竟然比不用还慢

真的很好写

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef unsigned long long ll;
const int N=1e5+,M=;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,Q,u,v,op,w[N];
int root;
struct Edge{
int v,ne;
}e[N<<];
int cnt,h[N];
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}
struct BIT{
ll c[N];
inline void add(int p,ll v){for(;p<=n;p+=(p&-p)) c[p]+=v;}
inline ll sum(int p){
ll re=;
for(;p;p-=(p&-p)) re+=c[p];
return re;
}
}C;
int block,m,pos[N];
int a[N],L[N],R[N],dfc;
int f[M][N];
void dfs(int u,int fa){
L[u]=++dfc;
a[pos[u]]++;
for(int i=;i<=m;i++) f[i][u]+=a[i]; for(int i=h[u];i;i=e[i].ne)
if(e[i].v!=fa) dfs(e[i].v,u); R[u]=dfc;
a[pos[u]]--;
}
ll subtree(int x){return C.sum(R[x])-C.sum(L[x]-);}
ll sum[N];
void Change(int x,int v){
C.add(L[x],v-w[x]);
for(int i=;i<=m;i++) sum[i]+=(ll)(v-w[x])*f[i][x];
w[x]=v;
}
ll Query(int l,int r){
ll re=;
if(pos[l]==pos[r])
for(int i=l;i<=r;i++) re+=subtree(i);
else{
int _=pos[l]*block;
for(int i=l;i<=_;i++) re+=subtree(i);
for(int i=(pos[r]-)*block+;i<=r;i++) re+=subtree(i);
for(int i=pos[l]+;i<pos[r];i++) re+=sum[i];
}
return re;
}
int main(){
freopen("in","r",stdin);
n=read();Q=read();
block=sqrt(n);
m=(n-)/block+;
for(int i=;i<=n;i++) w[i]=read();
for(int i=;i<=n;i++){
u=read();v=read();
if(u) ins(u,v); else root=v;
pos[i]=(i-)/block+;
}
dfs(root,);
for(int i=;i<=n;i++) C.add(L[i],w[i]);
for(int i=;i<=m;i++){
int l=(i-)*block+,r=min(i*block,n);
for(int j=l;j<=r;j++) sum[i]+=subtree(j);
}
while(Q--){
op=read();u=read();v=read();
if(op==) Change(u,v);
else printf("%llu\n",Query(u,v));
}
}

MashiroSky怎么这么快啊.....发现他一开始子树和写在dfs里我也改成那样啦怎么还是这么慢><.......

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef unsigned long long ll;
const int N=1e5+,M=;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,Q,u,v,op,w[N];
int root;
struct Edge{
int v,ne;
}e[N<<];
int cnt,h[N];
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}
struct BIT{
ll c[N];
inline void add(int p,ll v){for(;p<=n;p+=(p&-p)) c[p]+=v;}
inline ll sum(int p){
ll re=;
for(;p;p-=(p&-p)) re+=c[p];
return re;
}
}C;
int block,m,pos[N];
int a[N],L[N],R[N],dfc;
int f[M][N];
ll subtree(int x){return C.sum(R[x])-C.sum(L[x]-);}
ll sum[N];
ll dfs(int u,int fa){
L[u]=++dfc; a[pos[u]]++;
C.add(L[u],w[u]);
ll s=w[u];
for(int i=;i<=m;i++) f[i][u]+=a[i];
for(int i=h[u];i;i=e[i].ne)
if(e[i].v!=fa) s+=dfs(e[i].v,u);
R[u]=dfc; a[pos[u]]--;
sum[pos[u]]+=s;
return s;
}
void Change(int x,int v){
C.add(L[x],v-w[x]);
for(int i=;i<=m;i++) sum[i]+=(ll)(v-w[x])*f[i][x];
w[x]=v;
}
ll Query(int l,int r){
ll re=;
if(pos[l]==pos[r])
for(int i=l;i<=r;i++) re+=subtree(i);
else{
int _=pos[l]*block;
for(int i=l;i<=_;i++) re+=subtree(i);
for(int i=(pos[r]-)*block+;i<=r;i++) re+=subtree(i);
for(int i=pos[l]+;i<pos[r];i++) re+=sum[i];
}
return re;
}
int main(){
freopen("in","r",stdin);
n=read();Q=read();
block=;
m=(n-)/block+;
for(int i=;i<=n;i++) w[i]=read();
for(int i=;i<=n;i++){
u=read();v=read();
if(u) ins(u,v); else root=v;
pos[i]=(i-)/block+;
}
dfs(root,);
while(Q--){
op=read();u=read();v=read();
if(op==) Change(u,v);
else printf("%llu\n",Query(u,v));
}
}

BZOJ 4765: 普通计算姬 [分块 树状数组 DFS序]的更多相关文章

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

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

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

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

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

    4765: 普通计算姬 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 1725  Solved: 376[Submit][Status][Discus ...

  4. [bzoj4765]普通计算姬(分块+树状数组+DFS序)

    题意 给定一棵n个节点的带权树,节点编号为1到n,以root为根,设sum[p]表示以点p为根的这棵子树中所有节点的权值和.计算姬支持下列两种操作: 1 给定两个整数u,v,修改点u的权值为v. 2 ...

  5. BZOJ 1103 [POI2007]大都市meg(树状数组+dfs序)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1103 [题目大意] 给出一棵树,每条边的经过代价为1,现在告诉你有些路不需要代价了, ...

  6. 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序

    [题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...

  7. BZOJ 4765 普通计算姬 (分块 + BIT)

    4765: 普通计算姬 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 1547  Solved: 329[Submit][Status][Discus ...

  8. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  9. BZOJ.2434.[NOI2011]阿狸的打字机(AC自动机 树状数组 DFS序)

    题目链接 首先不需要存储每个字符串,可以将所有输入的字符依次存进Trie树,对于每个'P',记录该串结束的位置在哪,以及当前节点对应的是第几个串(当前串即根节点到当前节点):对于'B',只需向上跳一个 ...

随机推荐

  1. POJ_2769同余问题

    Reduced ID Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9310   Accepted: 374 ...

  2. CLR 简介

    (一)CLR介绍 CLR是一个可以由多编程语言使用的运行时,CLR的核心功能:内存管理,程序集加载,安全性,异常处理,线程同步等等.可以被很多属于微软系列的开发语言使用. 事实上,在运行时,CLR根本 ...

  3. 【android studio】 gradle配置成本地离线zip包

    http://blog.csdn.net/jingleye/article/details/52689260       关键词:distributionUrl修改成本地路径,android stud ...

  4. [国嵌笔记][014][Mini2440安装Linux]

    引导安装步骤 相关介绍: 开发板软件构成:Bootloader.嵌入式操作系统.嵌入式文件系统 JTAG接口常用于对flash等器件进行编程,常见的JTAG下载线有并口和USB接口两种 硬件连接: 1 ...

  5. Linux命令之远程下载命令:wget

    转自:http://www.cnblogs.com/peida/archive/2013/03/18/2965369.html Linux系统中的wget是一个下载文件的工具,它用在命令行下.对于Li ...

  6. dede从www跟目录迁移,网站空间

    图集缩略图表名dede_uploads                    字段url; 图集文章内部的图片表名dede_addonimages        字段imgurls 频道文章列表的图片 ...

  7. Python3 的数据类型

    Python3 的数据类型 整形,浮点型,布尔类型 类型转换 int() 整形 采用截断的方式即向下取整,比如 a=5.5 int (a) 返回值为5 怎样才能使int()按照"四舍五入&q ...

  8. Asp.net mvc 中的 Controller 的激活

    Controller 激活是指根据路由系统解析出来的 Controller 的名称创建 控制器(Controller)的过程,这里的控制器泛指实现了 IController 接口的类型 激活过程中的核 ...

  9. 给外行或者刚入门普及一下关于C#,.NET Framework(.NET框架),.Net,CLR,ASP,ASP.Net, VS,以及.NET Core的概念

    一.概念 1. C# :C#是微软公司发布的一种面向对象的.运行于.NET Framework之上的高级程序设计语言. 2..NET Framework(.NET框架):.NET framework ...

  10. iOS学习之Map,定位,标记位置的使用

    iOS上使用地图比Android要方便,只需要新建一个MKMapView,addSubView即可.这次要实现的效果如下: 有标注(大头针),定位,地图. 1.添加地图 1.1 新一个Single V ...