Given a rooted tree ( the root is node 11 ) of NN nodes. Initially, each node has zero point.

Then, you need to handle QQ operations. There're two types:

1\ L\ X1 L X: Increase points by XX of all nodes whose depth equals LL ( the depth of the root is zero ). (x \leq 10^8)(x≤108)

2\ X2 X: Output sum of all points in the subtree whose root is XX.

Input

Just one case.

The first lines contain two integer, N,QN,Q. (N \leq 10^5, Q \leq 10^5)(N≤105,Q≤105).

The next n-1n−1 lines: Each line has two integer aa,bb, means that node aa is the father of node bb. It's guaranteed that the input data forms a rooted tree and node 11 is the root of it.

The next QQ lines are queries.

Output

For each query 22, you should output a number means answer.

样例输入复制

3 3
1 2
2 3
1 1 1
2 1
2 3

样例输出复制

1
0

题目来源

ACM-ICPC 2018 沈阳赛区网络预赛

题意:

有一棵树 两种操作

一种是 将深度为i的所有节点的值加x

一种是 求以x为根的子树的所有节点之和

题解:

比赛的时候想到线段树 + dfs序了

也想到了将深度相同的节点用数组存

但是后面担心没办法维护修改 就有点不太会了

今天看题解的时候看到有一个人说  “ 一看这种没有办法直接用数据结构解决得问题就要考虑分块。”【学到了学到了】

对于同一深度设一个阈值limit,若这一深度中结点的个数>limit,则不实际进行更改,而是用一个数组来标记,因为>limit的层数不会太多,所以可以直接暴力枚举所有超越阈值的层数对于答案的贡献,同时二分答案即可。

节点数>block的为第一类,节点数<=为第二类。

对于第二类,每次修改操作我们暴力修改每个结点的影响值,因为涉及线段树或者树状数组的操作,时间复杂度为O(q*block*logn)。而每次通过线段树查询都是logn的

对于第一类,当修改的时候直接记录这一层被增加了多少,O(1)修改,然后查询的时候只需要枚举第二类的每一层,然后以这个结点为根节点的子树中属于这一层的节点数*这一层增加的值。这里的时间复杂度是O(q*n/block)

我们需要预处理出每个结点的子树中属于第一类层的节点数各有多少。这里我用的办法就是直接暴力。枚举每个点,如果它所在的层是第一类,那么更新它所有的父节点。这里的时间复杂度很容易被认为是O(n^2)。但是我们仔细分析一下发现它远远小于O(n^2)。因为最多有n/block层,所以这里的时间复杂度是O(n*n/block)

先不考虑预处理,只看操作的时间复杂度是O(q*block*logn+q*n/block).根据均值不等式最小是O(q*2*sqrt(nlogn)),当且仅当block取sqrt(n/logn)。这时候预处理的时间复杂度是O(n*sqrt(n*logn))经过计算时可以承受的(因为只有单组数据)。

 // ConsoleApplication3.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
// //#include "pch.h"
#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<set>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<stack> #define inf 0x3f3f3f3f using namespace std; typedef long long LL; const int maxn = 1e5 + ;
int n, q;
struct edge{
int v, nxt;
}e[maxn << ];
int head[maxn], cnt;
int cntid, st[maxn], ed[maxn];
vector<int>dep[maxn];
vector<int>large;
LL sum[maxn], num[maxn]; void init()
{
memset(head, -, sizeof(head));
memset(sum, , sizeof(sum));
memset(num, , sizeof(num));
cnt = ;
cntid = ;
} void addedge(int u, int v)
{
e[cnt].v = v;
e[cnt].nxt = head[u];
head[u] = cnt++;
} void dfs(int u, int fa, int depth)
{
st[u] = ++cntid;
dep[depth].push_back(cntid);
for(int i = head[u]; i != -; i = e[i].nxt){
int v = e[i].v;
if(v != fa){
dfs(v, u, depth + );
}
}
ed[u] = cntid;
} void add(int pos, LL x)
{
while(pos <= n){
sum[pos] += x;
pos += (pos & -pos);
}
} LL query(int pos)
{
LL ans = ;
while(pos){
ans += sum[pos];
pos -= (pos & -pos);
}
return ans;
} int main()
{
init();
scanf("%d%d", &n, &q);
for(int i = ; i < n; i++){
int u, v;
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
dfs(, , );
//cout<<"y"<<endl;
int block = ceil(sqrt(n));
for(int i = ; i < n; i++){//节点大于阈值的层
if(dep[i].size() > block){
large.push_back(i);
}
} while(q--){
int op;
scanf("%d", &op);
if(op == ){
int d;
LL x;
scanf("%d%lld", &d, &x);
if(dep[d].size() > block){
num[d] += x;
}
else{
for(int i = ; i < dep[d].size(); i++){
add(dep[d][i], x);//暴力修改
}
}
}
else{
int x;
scanf("%d", &x);
LL ans = query(ed[x]) - query(st[x] - );//查询子树中属于第二类的节点的部分
for(int i = ; i < large.size(); i++){
//查询所有第一类的层数中 属于这棵子树的节点 乘以盖层的修改值
ans += (upper_bound(dep[large[i]].begin(), dep[large[i]].end(), ed[x]) - lower_bound(dep[large[i]].begin(), dep[large[i]].end(), st[x])) * num[large[i]];
}
printf("%lld\n", ans);
}
} return ;
}

沈阳网络赛J-Ka Chang【分块】【树状数组】【dfs序】的更多相关文章

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

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

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

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

  3. 2019-ACM-ICPC-徐州站网络赛- I. query-二维偏序+树状数组

    2019-ACM-ICPC-徐州站网络赛- I. query-二维偏序+树状数组 [Problem Description] ​ 给你一个\([1,n]\)的排列,查询\([l,r]\)区间内有多少对 ...

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

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

  5. Trace 2018徐州icpc网络赛 (二分)(树状数组)

    Trace There's a beach in the first quadrant. And from time to time, there are sea waves. A wave ( xx ...

  6. 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树

    [BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...

  7. HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)

    Tree chain problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  8. 【BZOJ3653】谈笑风生 离线+树状数组+DFS序

    [BZOJ3653]谈笑风生 Description 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道高明到哪里去了”. ? 设a 和 ...

  9. BZOJ 2780 Sevenk Love Oimaster (后缀自动机+树状数组+dfs序+离线)

    题目大意: 给你$n$个大串和$m$个询问,每次给出一个字符串$s$询问在多少个大串中出现过 好神的一道题 对$n$个大串建出广义$SAM$,建出$parent$树 把字符串$s$放到$SAM$里跑, ...

  10. luogu SP8093 后缀自动机+树状数组+dfs序

    这题解法很多,简单说几个: 1. 线段树合并,时间复杂度是 $O(nlog^2n)$ 的. 2. 暴力跳 $fail,$ 时间复杂度 $O(n\sqrt n),$ 比较暴力. 3. 建立后缀树后在 $ ...

随机推荐

  1. e555. 在Applet中播放音频

    // See also e551 精简的Applet public void init() { // Load audio clip AudioClip ac = getAudioClip(getDo ...

  2. 应当将指针变量用“==”或“!=”与 NULL 比较

    应当将指针变量用“==”或“!=”与 NULL 比较. 指针变量的零值是“空”(记为 NULL). 尽管 NULL 的值与 0 相同,但是两者意义不 同. 假设指针变量的名字为 p,它与零值比较的标准 ...

  3. linux -- ubuntu 安装apache后,修改默认路径

    默认由apt方式安装的Apache,指定网页主目录位于:/var/www 而系统/var所分到的空间太少,所以要换路径 1.修改默认网站目录 ubuntu8.10下修改apache2的默认文档目录 默 ...

  4. C# HttpClientHelper请求

    public class HttpClientHelper { /// <summary> /// get请求 /// </summary> /// <param nam ...

  5. 【Java面试题】58 char型变量中能不能存贮一个中文汉字?为什么?

    char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中当然可以存储汉字啦.不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么 ...

  6. jquery轻量级富文本编辑器Trumbowyg

    html: <!DOCTYPE html> <html lang="zh-cn"> <head> <meta http-equiv=&qu ...

  7. Maven-使用及常见问题

    一.Maven是什么? 管理jar包用的,以前jar包是自己下载,然后放在lib下,然后add build Path,Maven环境下,只需要添加坐标(实际是xml片段)便会根据坐标自行下载. 二.M ...

  8. oracle之trunc(sysdate)

    --截取后得到的仍为date数据类型 select trunc(sysdate) from dual;--2017-03-13 00:00:00select trunc(sysdate+1) from ...

  9. Android开发之程序猿必需要懂得Android的重要设计理念2(5.20更新版)

    上篇文章介绍了Android开发的设计理念的一部分,并没有得到博友们的多大认可,仅仅看到了一位博友在以下留言期待下一篇文章的发表,为了这小小的唯一支持.我决定继续把后面的8个要点介绍一下,自己也潜心反 ...

  10. JAVA实现随机无重复数字功能

    本文给大家介绍如何在JAVA中实现随机无重复数字的功能.如果您是初学者的话,有必要看一看这篇文章,因为这个功能一般会在面试中遇到.包括我本人在招聘人员的时候也喜欢拿这个问题去问别人,主要看一看考虑问题 ...