题目链接:https://nanti.jisuanke.com/t/31451

Given a rooted tree ( the root is node $1$ ) of $N$ nodes. Initially, each node has zero point.

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

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

2 X: Output sum of all points in the subtree whose root is $X$.

Input
Just one case.

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

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

The next $Q$ lines are queries.

Output
For each query $2$, you should output a number means answer.

题意:

给出一棵 $N$ 个节点的树,初始每个节点的权值均为 $0$,接下来给出 $Q$ 个操作,有两种操作:

第一种,修改操作,对所有深度为 $L$ 的节点(根节点的深度为 $0$),权值加上 $X$;

第二种,查询操作,查询以节点 $X$ 为根节点的子树(包含节点 $X$)内所有节点的权值和。

题解:

说实话,比赛的时候,想到了DFS序+线段树的操作,但是不会搞时间复杂度卡死。然而,要知道,神仙的时间复杂度和蒟蒻的时间复杂度是不一样的。

以下根据官方题解:

设定一个层内节点数的阈值 $T$,

当第 $L$ 层的节点数 $size_L < T$ 时,用DFS序把树拍平,

  修改操作,可以直接暴力枚举所有节点进行 $O\left( {\log N} \right)$ 修改,时间复杂度为 $O\left( {T\log N} \right)$;

  查询操作,直接就是 $O\left( {\log N} \right)$ 区间查询。

因此,两种操作合起来的时间复杂度 $O\left( {Q \cdot T\log N} \right)$。

当第 $L$ 层的节点数 $size_L \ge T$ 时,

  修改操作,存储每一层节点的权值(因为同一层内节点的权值永远是一样的),直接 $O\left( 1 \right)$ 修改;

  查询操作,直接暴力枚举层,对于每一层,使用二分查找,得到属于“根为$X$的子树”的节点的个数,时间复杂度 $O\left( {\frac{N}{T}\log N} \right)$。

因此,两种操作合起来的时间复杂度 $O\left( {Q \cdot \frac{N}{T}\log N} \right)$。

因此总的时间复杂度为 $O\left( {Q\log N\left( {T + \frac{N}{T}} \right)} \right)$,所以令 $T = \sqrt N$ 最优,时间复杂度为 $O\left( {Q\sqrt N \log N} \right)$。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+; int n,q;
int T;
ll val_deep[maxn]; //存储深度为deep的节点的权值
vector<int> Node_deep[maxn]; //存储深度为deep的节点的编号
vector<int> bigL; //存储节点数不小于阈值的层编号 //邻接表-st
struct Edge{
int u,v;
Edge(int u=,int v=){this->u=u,this->v=v;}
};
vector<Edge> E;
vector<int> G[maxn];
void addedge(int u,int v)
{
E.push_back(Edge(u,v));
G[u].push_back(E.size()-);
}
//邻接表-ed //dfs序-st
int dfs_clock=;
int in[maxn],out[maxn];
void dfs(int now,int dep)
{
in[now]=++dfs_clock;
Node_deep[dep].push_back(in[now]);
for(int i=;i<G[now].size();i++)
{
int nxt=E[G[now][i]].v;
dfs(nxt,dep+);
}
out[now]=dfs_clock;
}
//dfs序-ed struct _BIT{
int N;
ll C[maxn];
int lowbit(int x){return x&(-x);}
void init(int n) //初始化共有n个点
{
N=n;
for(int i=;i<=N;i++) C[i]=;
}
void add(int pos,ll val) //在pos点加上val
{
while(pos<=N)
{
C[pos]+=val;
pos+=lowbit(pos);
}
}
ll sum(int pos) //查询1~pos点的和
{
ll ret=;
while(pos>)
{
ret+=C[pos];
pos-=lowbit(pos);
}
return ret;
}
}BIT; int main()
{
cin>>n>>q;
T=((n>)?(int)sqrt(n):n);
for(int i=;i<n;i++)
{
int par,son; scanf("%d%d",&par,&son);
addedge(par,son);
} dfs(,); for(int dep=;dep<=n;dep++)
{
if(Node_deep[dep].size()>=T) bigL.push_back(dep);
} BIT.init(n);
memset(val_deep,,sizeof(val_deep));
for(int i=;i<=q;i++)
{
int type; scanf("%d",&type);
if(type==)
{
int L,X; scanf("%d%d",&L,&X);
if(Node_deep[L].size()<T)
for(int k=;k<Node_deep[L].size();k++) BIT.add(Node_deep[L][k],(ll)X);
else
val_deep[L]+=X;
}
else
{
int X; scanf("%d",&X);
ll ans=BIT.sum(out[X])-BIT.sum(in[X]-);
for(int k=;k<bigL.size();k++)
{
int dep=bigL[k];
int L=lower_bound(Node_deep[dep].begin(),Node_deep[dep].end(),in[X])-Node_deep[dep].begin();
int R=upper_bound(Node_deep[dep].begin(),Node_deep[dep].end(),out[X])-Node_deep[dep].begin();
ans+=(R-L)*val_deep[dep];
}
printf("%lld\n",ans);
}
}
}

评测结果:

可以看到,名字叫卡常的题目是最不卡常的。

计蒜客 31451 - Ka Chang - [DFS序+树状数组][2018ICPC沈阳网络预赛J题]的更多相关文章

  1. 计蒜客 青出于蓝胜于蓝(dfs序+树状数组)

    题目描述 武当派一共有 n 人,门派内 n 人按照武功高低进行排名,武功最高的人排名第 1,次高的人排名第 2,... 武功最低的人排名 第 n.现在我们用武功的排名来给每个人标号,除了祖师爷,每个人 ...

  2. 计蒜客A1998 Ka Chang (分块+dfs序+树状数组)

    题意 给你一个\(1e5\)的有点权的树,有\(1e5\)个操作: 1.给第\(x\)层的点加上\(y\) 2.求以\(x\)为根的子树的点权和 思路 首先处理出层数为x的所有点 操作2一般都是用df ...

  3. HDU 3887:Counting Offspring(DFS序+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...

  4. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  5. 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 ...

  6. BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

    一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...

  7. 【bzoj3881】[Coci2015]Divljak AC自动机+树链的并+DFS序+树状数组

    题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  8. [BZOJ1103][POI2007]大都市meg dfs序+树状数组

    Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n ...

  9. 2018.10.20 NOIP模拟 巧克力(trie树+dfs序+树状数组)

    传送门 好题啊. 考虑前面的32分,直接维护后缀trietrietrie树就行了. 如果#号不在字符串首? 只需要维护第一个#前面的字符串和最后一个#后面的字符串. 分开用两棵trie树并且维护第一棵 ...

随机推荐

  1. Dubbo -- 系统学习 笔记 -- 示例 -- 负载均衡

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 负载均衡 在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调 ...

  2. 搭建Vue.js环境,建立一个简单的Vue项目

    基于vue-cli快速构建 Vue是近年来比较火的一个前端框架,所以搭建Vue.js环境,要装webpack,vue-cli,Vue 安装webpack命令如下 $ cnpm install webp ...

  3. Maven发布war包到Tomcat

    一.修改Tomcat下配置文件tomcat-users.xml,然后启动 <role rolename="manager-gui"/> <role rolenam ...

  4. mybatis generator配置,Mybatis自动生成文件配置,Mybatis自动生成实体Bean配置

    mybatis generator配置,Mybatis自动生成文件配置,Mybatis自动生成实体Bean配置 ============================== 蕃薯耀 2018年3月14 ...

  5. 利用DB实现简单去重处理

    业务需要针对某文件进行判重操作,用Perl实现如下 #!/usr/bin/perl my %h; s/\s+$// and $h{$_}++ while <>; print "$ ...

  6. [Ubuntu] 如何设置静态 IP 和 DNS

    编辑 /etc/network/interfaces 来设置 IP 和 DNS 解析服务器: # interfaces() ) and ifdown() auto lo iface lo inet l ...

  7. 中文解码Unicode

    package com.j1.search.utils; import java.io.UnsupportedEncodingException; import java.net.URLDecoder ...

  8. 普通for循环和增强for循环的区别

    1.普通for循环:自行维护循环次数,循环体自行维护获取元素的方法: int[] array = new int[]{1,2,3,4,5}; //int[] array ={1,2,3,4,5} ; ...

  9. Mac下Intellij IDea发布JavaWeb项目 详解一 (1、新建JavaEE Project并进行相应设置 2、配置tomcat)

    IDEA中 javaWeb项目的创建和tomcat配置(完整) 1.先新建JavaEE Project并进行相应设置 2.在配置tomcat Step1 新建JavaEE Project并进行相应设置 ...

  10. (原)强类型dataset(类型化dataset)中动态修改查询条件(不确定参数查询)

    原创博客,转载请注明:http://www.cnblogs.com/albert1017/p/3361932.html 查询时有多个参数,参数个数由客户输入决定,不能确定有多少个参数,按一般的方法每种 ...