计蒜客A1998 Ka Chang (分块+dfs序+树状数组)
题意
给你一个\(1e5\)的有点权的树,有\(1e5\)个操作:
1.给第\(x\)层的点加上\(y\)
2.求以\(x\)为根的子树的点权和
思路
首先处理出层数为x的所有点
操作2一般都是用dfs序+树状数组/线段树,这题因为它奇怪的题目名字,选择了树状数组
而操作1如果直接暴力的话,复杂度将是\(O(nlogn)\)的,我们想办法把这个复杂度尽量摊到操作2上去
因为只是对层数为\(x\)的增加点权,操作1操作的点数取决于层数为\(x\)的点的个数,我们可以分块
如果操作1要处理的点数超过\(m\),就把m这一层打个标记,否则暴力,复杂度\(O(mlogn)\)
对于操作2,我们\(logn\)得到子树中点数小于\(m\)的层的答案后,从点数大于\(m\)的层中二分算出贡献,复杂度\(O(\frac{n}{m}logn)\)
由于我们是用dfs序来得到每层中的所有点的,所以x的所有同一层的孩子在这里连续,所以可以二分
总复杂度\(O(q(mlogn+\frac{n}{m}))\)
所以\(m=\sqrt{n}\)
复杂度\(O(qlog\sqrt{n}logn)\)
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>
#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
using namespace std;
typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;
const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 2e5+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);
int n,q,m;
vector<int>v[maxn],g[maxn],G;
ll tree[maxn];
int tot;
int lowbit(int x){return x&(-x);}
void add(int x, ll c){
for(int i = x; i <= n; i+=lowbit(i))tree[i]+=c;
}
ll sum(int x){
ll ans = 0;
for(int i = x; i; i-=lowbit(i))ans+=tree[i];
return ans;
}
int S[maxn],bg[maxn],ed[maxn];
int dep[maxn];
void dfs(int x, int dp){
bg[x]=++tot;
g[dp].pb(tot);
for(int i = 0; i < (int)v[x].size(); i++){
int y = v[x][i];
dfs(y,dp+1);
}
ed[x]=tot;
}
ll C[maxn];
int main() {
scanf("%d %d", &n, &q);
m = (int)sqrt(n);
for(int i = 1; i < n; i++){
int x, y;
scanf("%d %d", &x, &y);
v[x].pb(y);
}
dfs(1,0);
for(int i = 0; i <= n; i++){
if(g[i].size()>m){
G.pb(i);
}
}
while(q--){
int op,x,y;
scanf("%d %d", &op,&x);
if(op==1){
scanf("%d", &y);
if((int)g[x].size()<=m){
for(int i = 0; i <(int)g[x].size(); i++){
int to = g[x][i];
add(to,y);
}
}
else C[x]+=y;
}
else{
ll ans = sum(ed[x])-sum(bg[x]-1);
for(int i = 0; i < (int)G.size(); i++){
int y = G[i];
int L=-1,R=-1;
int l=0,r=g[y].size()-1;
while(l<=r){
int mid = l+r>>1;
if(g[y][mid]>=bg[x]){
L=mid;
r=mid-1;
}
else l=mid+1;
}
l=0,r=g[y].size()-1;
while(l<=r){
int mid = l+r>>1;
if(g[y][mid]<=ed[x]){
R=mid;
l=mid+1;
}
else r=mid-1;
}
if(L<=R&&L!=-1&&R!=-1)ans+=C[y]*(R-L+1);
}
printf("%lld\n",ans);
}
}
return 0;
}
计蒜客A1998 Ka Chang (分块+dfs序+树状数组)的更多相关文章
- BZOJ_4765_普通计算姬_分块+dfs序+树状数组
BZOJ_4765_普通计算姬_分块 Description "奋战三星期,造台计算机".小G响应号召,花了三小时造了台普通计算姬.普通计算姬比普通计算机要厉害一些 .普通计算机能 ...
- HDU 3887:Counting Offspring(DFS序+树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...
- HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
- Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组
C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...
- BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )
一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...
- 【bzoj3881】[Coci2015]Divljak AC自动机+树链的并+DFS序+树状数组
题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...
- [BZOJ1103][POI2007]大都市meg dfs序+树状数组
Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n ...
- 2018.10.20 NOIP模拟 巧克力(trie树+dfs序+树状数组)
传送门 好题啊. 考虑前面的32分,直接维护后缀trietrietrie树就行了. 如果#号不在字符串首? 只需要维护第一个#前面的字符串和最后一个#后面的字符串. 分开用两棵trie树并且维护第一棵 ...
- HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca
Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...
随机推荐
- 安装 redis
官方下载地址:http://redis.io/download,但是官方没有64位的Windows下的可执行程序. 目前有个开源的托管在github上, 地址:https://github.com/S ...
- FlashFXP中文破解 指南
flashfxp是一款使用非常广泛,功能非常更强大的FXP/FTP软件.它拥有显示彩色文字.比较CuteFTP的目录.上传和下载文件.共享文件等众多功能,其中深受用户喜爱的便是目录比较功能,它能够有效 ...
- Java 从入门到进阶之路(二十二)
在之前的文章我们介绍了一下 Java 中的 集合框架中的Collection 中的一些常用方法,本章我们来看一下 Java 集合框架中的Collection 的迭代器 Iterator. 当我们创建 ...
- LGV - 求多条不相交路径的方案数
推荐博客 :https://blog.csdn.net/qq_25576697/article/details/81138213 链接:https://www.nowcoder.com/acm/con ...
- sg函数的变形 - 可以将一堆石子分开
Nim is a two-player mathematic game of strategy in which players take turns removing objects from di ...
- 如何添加.pch文件
1.Create a pch , call name is project+xxx.pch For example: DuoME-PrefixHeader.pch 2.在project——>Bu ...
- java常量 数据类型
一.常量 概念:程序运行期间,内容不发生改变的量 1.字符串常量 双引号 2.整数常量 3.浮点数常量 4.字符常量 单引号 一个字符 必须要有一个字符 不能为空 5.布尔常量 true false ...
- springboot下Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
已检查jar包是否引入 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId ...
- [bzoj3529] [洛谷P3312] [Sdoi2014] 数表
Description 有一张n×m的数表,其第i行第j列(1 < =i < =n,1 < =j < =m)的数值为 能同时整除i和j的所有自然数之和.给定a,计算数表中不大于 ...
- 「 深入浅出 」集合Map
系列文章: 「 深入浅出 」java集合Collection和Map 「 深入浅出 」集合List 「 深入浅出 」集合Set 前面已经介绍完了Collection接口下的集合实现类,今天我们来介绍M ...