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优步司机奖励政策(1月28日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 宁波Uber优步司机奖励政策(12月21日到12月27日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- LeetCode: 60. Permutation Sequence(Medium)
1. 原题链接 https://leetcode.com/problems/permutation-sequence/description/ 2. 题目要求 给出整数 n和 k ,k代表从1到n的整 ...
- MyBatis-MBG(MyBatis Generator)
1.添加jar包 <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>m ...
- Redis系列五 Redis持久化
Redis持久化 一.RDB(Redis DataBase) 1.介绍 在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里. Red ...
- Net Core学习笔记
Net Core 官网:https://dotnet.github.io/ Net Core Api: https://docs.microsoft.com/en-us/dotnet/api/?vie ...
- Siki_Unity_2-1_API常用方法和类详细讲解(上)
Unity 2-1 API常用方法和类详细讲解(上) 任务1&2:课程前言.学习方法 && 开发环境.查API文档 API: Application Programming I ...
- leetcode-回文链表
请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶:你能否用 O(n) 时间复杂 ...
- sparksql读写hbase
//写入hbase(hfile方式) org.apache.hadoop.hbase.client.Connection conn = null; try { SparkLog.debug(" ...
- browsersync 插件
自从发现了这个 browsersync 插件 ... 在也不用每次改一行代码就去手动刷新 HTML 页面了省去了很多繁琐的操作,当有多个显示器的时候,更加的方便,在IDEA上编辑代码之后,点击 com ...