对节点按编号分块。设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. jsp内置的对象【jsp可用数据容器】

    jsp的内置对象用法:可以存放数据进去,本身页面可以调用,发生页面请求时,请求目标可以调用 理解:jsp就是一个大容器,有请求,响应等内置对象,会话需要从请求容器中提取 请求中内置session,发出 ...

  2. VIO 初始化小结 - 10.17

    最近几个月忙于博士毕业,找工作一直没有继续更新博客,希望以这一篇开始,每个月能够继续有几篇总结博客. 首先review一下比较著名的vio系统 Tightly coupled EKF: mainly ...

  3. wireshark抓包分析——TCP/IP协议

    本文来自网易云社区 当我们需要跟踪网络有关的信息时,经常会说"抓包".这里抓包究竟是什么?抓到的包又能分析出什么?在本文中以TCP/IP协议为例,简单介绍TCP/IP协议以及如何通 ...

  4. Django自定义管理表单

    修改polls/admin.py: from django.contrib import admin from .models import Choice, Question class Choice ...

  5. linux部署MantisBT(二)部署php

    二.部署php 1.下载php安装包 http://php.net/downloads.php 2.安装php yum install libxml2 yum install libxml2-deve ...

  6. Java开发工程师(Web方向) - 03.数据库开发 - 第3章.SQL注入与防范

    第3章--SQL注入与防范 SQL注入与防范 经常遇到的问题:数据安全问题,尤其是sql注入导致的数据库的安全漏洞 国内著名漏洞曝光平台:WooYun.org 数据库泄露的风险:用户信息.交易信息的泄 ...

  7. Oracle启动与关闭数据库实例

    Oracle数据库启动实例分为3个步骤: 启动实例 加载数据库 打开数据库 通用模式: STARTUP  [ nomount | mount | open | force ]  [resetrict] ...

  8. 关于@media不生效的问题和meta总结

    1:之前做的是两套页面.现在改成响应式布局.发现加上 @media only screen and (max-width: 500px) {    .gridmenu {        width:1 ...

  9. anaconda安装scrapy报错解决办法

    今天在用anaconda安装scrapy的时候遇见个坑,现在将解决办法发出来,供大家参考使用: 问题描述: anaconda安装scrapy,使用 conda install scrapy 命令.安装 ...

  10. vmware中三种网络连接方式

    原文来自http://note.youdao.com/share/web/file.html?id=236896997b6ffbaa8e0d92eacd13abbf&type=note vmw ...