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. 【问题】报错[CRITICAL] Rendering SLS 'base:minions.install' failed: Jinja variable 'list' object has no element 0

    1.报错[CRITICAL] Rendering SLS 'base:minions.install' failed: Jinja variable 'list' object has no elem ...

  2. c# 异步编程demo (async await)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  3. 【Java面试题】12 内部类可以引用它的包含类的成员吗?有没有什么限制?

    完全可以.如果不是静态内部类,那没有什么限制! 如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员,例如,下面的代码: class Ou ...

  4. 下次不用找了,all language code

    语言 ID 语言 ID 决定网站中网页文本(例如“网站设置”页上的文本)使用的语言.创建网站时可用的语言取决于在服务器或服务器场中安装的语言模板包.基于 Windows SharePoint Serv ...

  5. [转]wcout输出中文却不显示出来

    准备使用UNICODE来写个控制台测试程序发现,cout无法输出UNICODE的中文字符.查找C++标准看到,其提供了wcin.wcout.wcerr.wclog用于处理wchar_t字符的输入输出. ...

  6. 好的 Web 前端年薪会有多少?

    只是一个范围参考,主要是看能力而定. 1. 切图熟练.能写一些JS效果(HTML+CSS+jQuery):5K~10K+2. 具备第一条,并可以熟练用JS开发各种组件:8K-15K+3. 具备第二条, ...

  7. mysql中如何在命令行中,执行一个SQL脚本文件?

    需求描述: 在mysql数据库的使用中,有的时候,需要直接在shell的命令行中,执行某个SQL脚本文件, 比如,要初始化数据库,创建特定的存储过程,创建表等操作,这里进行一个基本的测试. 一般情况, ...

  8. Extjs3.4--TabpanelDemo

    Ext.onReady(function () { var tab = new Ext.TabPanel({ renderTo: Ext.getBody(), height: 500 }) tab.a ...

  9. Javascript中的感叹号和函数function

    js函数前加分号和感叹号是什么意思?有什么用?:http://www.cnblogs.com/mq0036/p/4605255.html function与感叹号:https://swordair.c ...

  10. python2.0_s12_day19_前端模版使用

    Django中引用bootstrap实现在前端可以创建客户信息,可以修改客户信息我们需要设计一个前端用户交互系统.我们在设计之前,讨论一些需求:前端实现:1. 不同角色的用户,看到的东西是不一样的 销 ...