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. Spring 4 官方文档学习(十一)Web MVC 框架之URI Builder

    http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-uri-building ...

  2. 第二百八十八节,MySQL数据库-索引、limit分页、执行计划、慢日志查询

    MySQL数据库-索引.limit分页.执行计划.慢日志查询 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获 ...

  3. ARP协议相关介绍

    什么是ARP协议? ARP,即地址解析协议,实现通过IP地址得知其物理地址.在TCP/IP网络环境下,每个主机都分配了一个32位的IP地址,这种互联网地址是在网际范围标识主机的一种逻辑地址.为了让报文 ...

  4. (转)x264参数中文详解(X264 Settings)

    0 解释x264命令可选项的用途和使用方法.同执行 x264 --fullhelp 显示顺序.本文主要翻译:mewiki.project357.com/wiki/X264_Settings,同时参考d ...

  5. CentOS下添加sudo用户

    一 .sodo的使用 1.1 关于sudo Sudo是linux系统中,非root权限的用户提升自己权限来执行某些特性命令的方式,它使普通用户在不知道超级用户的密码的情况下,也可以暂时的获得root权 ...

  6. [精]Odoo 8.0深入浅出开发教程-模块开发基础

    參考资料点击这里. 构建Odoo模块 模块组成 业务对象 业务对象声明为Python类, 由Odoo自己主动加载. 数据文件 XML或CSV文件格式, 在当中声明了元数据(视图或工作流).配置数据(模 ...

  7. [转]NMON服务器监控、指标说明

    一.NMON中的各项参数指标: SYS_SUMM:显示当前服务器的总体性能情况 Total System I/OStatistics:Avg tps during an interval:显示采集间隔 ...

  8. Unity 大版本更新之APK的下载与覆盖安装

    作为一个游戏开发者,更新这个技能是必不可少的!更新分为游戏内的更新,也就是所谓的资源热更包括AssetBundle更新和代码更新,代码其实也是所谓的二进制文件,在安卓上和普通资源文件毫无差异,然而在I ...

  9. nginx配置语法

    http://baijiahao.baidu.com/s?id=1604485941272024493&wfr=spider&for=pc http://blog.csdn.net/h ...

  10. Sublime Text2安装Package Control

    一.安装Package Control 使用Sublime Text2首先就要安装Package Control,这样就能使用丰富的插件包了 安装方法有2种: (1)访问Package Control ...