对节点按编号分块。设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 普通计算姬(分块+树状数组)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. spring源码-bean之初始化-1

    一.spring的IOC控制反转:控制反转——Spring通过一种称作控制反转(IOC)的技术促进了松耦合.当应用了IOC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查 ...

  2. 容器云技术:容器化微服务,Istio占C位出道

    在精彩的软件容器世界中,当新项目涌现并解决你认为早已解决的问题时,这感觉就像地面在你的脚下不断地移动.在许多情况下,这些问题很久以前被解决,但现在的云原生架构正在推动着更大规模的应用程序部署,这就需要 ...

  3. debian8+lnmp1.2一键安装+WordPress3.9

    下载并安装LNMP一键安装包 wget -c http://soft.vpser.net/lnmp/lnmp1.2-full.tar.gz && tar zxf lnmp1.2-ful ...

  4. 了解Python控制流语句——while 语句

    while 语句 Python 中 while 语句能够让你在条件为真的前提下重复执行某块语句. while 语句是 循环(Looping) 语句的一种.while 语句同样可以拥有 else 子句作 ...

  5. post接口_ajax上传

    Action() { web_reg_save_param("find_msg", "LB=message\":\"", "RB= ...

  6. 【shell 每日一练6】初始化安装Mysql并修改密码

    一.简单实现mysql一键安装 参考:[第二章]MySQL数据库基于Centos7.3-部署 此脚本前提条件是防火墙,selinux都已经设置完毕: [root@web130 ~]# cat Inst ...

  7. New Year and Old Property :dfs

    题目描述: Limak is a little polar bear. He has recently learnt about the binary system. He noticed that ...

  8. 统计学习三:1.k近邻法

    全文引用自<统计学习方法>(李航) K近邻算法(k-nearest neighbor, KNN) 是一种非常简单直观的基本分类和回归方法,于1968年由Cover和Hart提出.在本文中, ...

  9. POJ 3845 Fractal(计算几何の旋转缩放)

    Description Fractals are really cool mathematical objects. They have a lot of interesting properties ...

  10. java知乎爬虫

    好久没写博客了,前阵子项目忙着上线,现在有点空闲,就把最近写的一个爬虫和大家分享下,统计结果放在了自己买的阿里云服务器上(点此查看效果),效果如下: 程序是在工作之余写的,用了java 的webmgi ...