COGS 2211. [BZOJ3653]谈笑风生
★★★★ 输入文件:laugh.in 输出文件:laugh.out 简单对比
时间限制:3 s 内存限制:512 MB
【问题描述】
设T 为一棵有根树,我们做如下的定义:
• 设a和b为T 中的两个不同节点。如果a是b的祖先,那么称“a比b不知道高明到哪里去了”。
• 设a 和 b 为 T 中的两个不同节点。如果 a 与 b 在树上的距离不超过某个给定常数x,那么称“a 与b 谈笑风生”。
给定一棵n个节点的有根树T,节点的编号为1 n,根节点为1号节点。你需要回答q 个询问,询问给定两个整数p和k,问有多少个有序三元组(a; b; c)满足:
1. a、b和 c为 T 中三个不同的点,且 a为p 号节点;
2. a和b 都比 c不知道高明到哪里去了;
3. a和b 谈笑风生。这里谈笑风生中的常数为给定的 k。
【输入格式】
输入文件的第一行含有两个正整数n和q,分别代表有根树的点数与询问的个数。接下来n-1行,每行描述一条树上的边。每行含有两个整数u和v,代表在节点u和v之间有一条边。接下来q 行,每行描述一个操作。第i行含有两个整数,分别表示第i个询问的p和k。
【输出格式】输出 q 行,每行对应一个询问,代表询问的答案。
laugh.in
5 3
1 2
1 3
2 4
4 5
2 2
4 1
2 3
laugh.out
3
1
3
数据范围 n<=300,000吧
主席树+dfs序
从要求看来,可以划分成两种情况:
1.b比a高明且a和b谈笑风生,那么c只需在a的子树中取就好了,此时贡献为size[p]*min(dep[p-1],k)
2.a比b高明且a和b谈笑风生,c在b的子树上,考虑到子树问题,想到dfs序,那么问题变为求子树a区间中深度在deep[p]+1~deep[p]+k中所有点size的和 ,这可以用主席树完成
#include <ctype.h>
#include <vector>
#include <cstdio>
#define N 305000
typedef long long LL; using std::vector;
struct cmt
{
int l,r;
LL Size;
}tr[N*];
inline void Read(int &x)
{
register char ch=getchar();
for(x=;!isdigit(ch);ch=getchar());
for(;isdigit(ch);x=x*+ch-'',ch=getchar());
}
LL ans;
int min(int a,int b) {return a>b?b:a;}
int max(int a,int b) {return a>b?a:b;}
vector<int>edge[N];
int t[N],dfn[N],l[N],r[N],n,q,dep[N],tim,siz[N],tot;
void dfs(int x,int fa)
{
l[x]=++tim;
dfn[tim]=x;
dep[x]=dep[fa]+;
siz[x]=;
for(int i=;i<edge[x].size();++i)
{
int v=edge[x][i];
if(v!=fa)
{
dfs(v,x);
siz[x]+=siz[v]+;
}
}
r[x]=tim;
}
void update(int l,int r,int x,int &y,int a,int b)
{
y=++tot;
tr[y].Size=tr[x].Size+b;
if(l==r) return;
tr[y].l=tr[x].l;
tr[y].r=tr[x].r;
int mid=(l+r)>>;
if(a<=mid) update(l,mid,tr[x].l,tr[y].l,a,b);
else update(mid+,r,tr[x].r,tr[y].r,a,b);
}
LL ask(int l,int r,int x,int y,int a,int b)
{
if(l==a&&r==b) return tr[y].Size-tr[x].Size;
int mid=(l+r)>>;
if(a>mid) return ask(mid+,r,tr[x].r,tr[y].r,a,b);
else if(b<=mid) return ask(l,mid,tr[x].l,tr[y].l,a,b);
else return ask(l,mid,tr[x].l,tr[y].l,a,mid)+ask(mid+,r,tr[x].r,tr[y].r,mid+,b);
}
int main(int argc,char *argv[])
{
freopen("laugh.in","r",stdin);
freopen("laugh.out","w",stdout);
Read(n);
Read(q);
for(int u,v,i=;i<n;++i)
{
Read(u);
Read(v);
edge[u].push_back(v);
edge[v].push_back(u);
}
dfs(,);
for(int i=;i<=n;++i) update(,n,t[i-],t[i],dep[dfn[i]],siz[dfn[i]]);
for(int p,k;q--;)
{
Read(p);
Read(k);
ans=;
ans=(LL)siz[p]*min(dep[p]-,k);
if(dep[p]!=n) ans+=ask(,n,t[l[p]-],t[r[p]],dep[p]+,min(n,dep[p]+k));
printf("%lld\n",ans);
}
return ;
}
COGS 2211. [BZOJ3653]谈笑风生的更多相关文章
- 数据结构(主席树):COGS 2211. 谈笑风生
2211. 谈笑风生 ★★★★ 输入文件:laugh.in 输出文件:laugh.out 简单对比时间限制:3 s 内存限制:512 MB [问题描述] 设T 为一棵有根树,我们做如下 ...
- BZOJ3653: 谈笑风生
Description 设T 为一棵有根树,我们做如下的定义:• 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道高明到哪里去了”.• 设a 和 b 为 T 中的两个不同节点.如 ...
- BZOJ3653谈笑风生——可持久化线段树+dfs序
题目描述 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道 高明到哪里去了”. ? 设a 和 b 为 T 中的两个不同节点.如果 a ...
- 2019.01.19 bzoj3653: 谈笑风生(长链剖分优化dp)
传送门 长链剖分优化dpdpdp水题. 题意简述:给一棵树,mmm次询问,每次给一个点aaa和一个值kkk,询问满足如下条件的三元组(a,b,c)(a,b,c)(a,b,c)的个数. a,b是c的祖先 ...
- 【主席树】bzoj3653 谈笑风生
设siz[i]表示i的子树大小-1. 询问中b在a上方的便于统计. 对于b在a下方的情况,贡献为距a距离在K以内的节点的siz之和. 按dfs序建立可持久化线段树,线段树的下标是深度. 相当于把每个点 ...
- [BZOJ3653]谈笑风生 主席树
题面 这道题应该比较裸吧. \(a\),\(b\)都是\(c\)的祖先. 那么第一种情况是\(b\)是\(a\)的祖先,那么方案数就是\(\min\{dep[a]-1,k\}\cdot (num[a] ...
- 【BZOJ3653】谈笑风生(长链剖分)
[BZOJ3653]谈笑风生(长链剖分) 题面 BZOJ 洛谷 权限题啊.... 题解 首先根据题目给的条件,发现\(a,b\)都要是\(c\)的父亲. 所以这三个点是树上的一条深度单增的链. 因为\ ...
- 【BZOJ3653】谈笑风生 离线+树状数组+DFS序
[BZOJ3653]谈笑风生 Description 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道高明到哪里去了”. ? 设a 和 ...
- 【BZOJ-3653】谈笑风生 DFS序 + 可持久化线段树
3653: 谈笑风生 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 628 Solved: 245[Submit][Status][Discuss] ...
随机推荐
- Robot FrameWork基础学习(三)
一.关键字(Keyword)根据架构的区分可分为以下三层结构: 底层关键字.公共层关键字.特性关键字. 底层关键字一般与最底层的代码在关系,为上层公共关键字和特性关键字提供接口. 公共层关键字:一般是 ...
- 利用python数据分析panda学习笔记之Series
1 Series a:类似一维数组的对象,每一个数据与之相关的数据标签组成 b:生成的左边为索引,不指定则默认从0开始. from pandas import Series,DataFrame imp ...
- 关于weblogic 10.3.6.0 的漏洞复现(1)
最近小R 搭建了个weblogic, 因为之前在公司找系统漏洞的时候,发现了这个漏洞,所以为了特地专门搭建了个10.3.6.0版本. 漏洞编号: CVE-2017-10271 漏洞的描述:就是web ...
- 真正可用的Asdoc生成工具及技巧和注意事项
经过一个上午的折腾,终于总结出一套完全能够正确运行得到asdoc api的工具.使用方便,里面写了许多注意事项,帮你顺利完成 api 的生成. :: 注意: :: 1.所以 ...
- 利用StringBuffer来替换内容
package com.test.java; public class StringBufferTest { public static void main(String[] args) { Stri ...
- Qt中csv文件的导入与导出
转自:http://blog.csdn.net/mingxia_sui/article/details/7683030 CSV 1.简介: 全称:Comma Separated Values. 是“逗 ...
- POJ3737【数学】
高中数学题?初中吧///然后注意一下POJ的double输出用%f.......... #include <iostream> #include <stdio.h> #incl ...
- MongoDb 创建用户以及其他版本造成的一些问题
问题:require auth data to have schema version 3 but found 1 这是可以查看如下链接: http://stackoverflow.com/quest ...
- jmeter beanshell处理请求响应结果时Unicode编码转为中文
在Test Plan下创建一个后置BeanShell PostProcessor,粘贴如下代码即可: String s=new String(prev.getResponseData()," ...
- 【转】String hashCode 方法为什么选择数字31作为乘子
某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主角31.这个 ...