【CF516D】Drazil and Morning Exercise
首先我们知道,在树上距离一个点最远的点一定是直径的两个端点之一
首先两遍\(\rm dfs\)把直径求出来,定义\(d(u)\)表示点\(u\)距离其最远点的距离,有了直径我们就能求出\(d\)数组了
当然可以树形\(\rm dp\),设\(f_{x,i,j}\)表示在\(x\)子树内部选择一个最大值为\(i\)最小值为\(j\)的最大联通块是多少,显然这样的复杂度奇高无比
考虑把求出的直径来好好利用一下
首先感性的发现一下,设\(x\)为直径中点,那么\(d(x)\)肯定是最小的点权,又发现我们钦定\(x\)为根,那么一个点的点权肯定比其子树内部的点都要小
那么我们就钦定\(x\)为根,之后枚举一个联通块的最高点\(i\),也就是点权的最小值
由于深度越大点权越大,于是我们就把这个子树内部所有点权不超过\(d(i)+L\)的点都选上,这显然构成一个联通块
于是问题转化成了求一个子树内部有多少个点的点权小于某个给定值,不难发现这是主席树裸题
说的好,于是我选择\(\rm dsu\ on\ tree\),复杂度\(O(nq\log n+n\log^2n)\),莫名其妙跑得比并查集老哥们快
代码
#include<bits/stdc++.h>
#define re register
#define LL long long
#define lb(x) ((x)&(-x))
#define max(a,b) ((a)>(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=1e5+5;
struct E{int v,nxt,w;}e[maxn<<1];
int n,m,num,Rt,rt,sz,S;
int head[maxn],sum[maxn],son[maxn],pos[maxn],dep[maxn],d[maxn],Ans[55];
LL pre[maxn],mx[maxn],q[55],c[maxn];
inline void add(int x,int y,int w) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;e[num].w=w;
}
inline int find(LL x) {
int l=1,r=sz,now=0;
while(l<=r) {
int mid=l+r>>1;
if(c[mid]<=x) now=mid,l=mid+1;else r=mid-1;
}
return now;
}
void dfs(int x,int fa) {
for(re int i=head[x];i;i=e[i].nxt) {
if(e[i].v==fa) continue;
pre[e[i].v]=pre[x]+e[i].w;
dfs(e[i].v,x);
}
}
void dfs1(int x) {
sum[x]=1;
for(re int i=head[x];i;i=e[i].nxt) {
if(dep[e[i].v]) continue;
dep[e[i].v]=dep[x]+1;dfs1(e[i].v);sum[x]+=sum[e[i].v];
if(sum[e[i].v]>sum[son[x]]) son[x]=e[i].v;
}
}
inline void add(int x,int v) {
for(re int i=x;i<=sz;i+=lb(i)) d[i]+=v;
}
inline int ask(int x) {
int now=0;
for(re int i=x;i;i-=lb(i)) now+=d[i];
return now;
}
void calc(int x,int o) {
add(pos[x],o);
for(re int i=head[x];i;i=e[i].nxt)
if(dep[e[i].v]>dep[x]&&S!=e[i].v) calc(e[i].v,o);
}
void dsu(int x,int k) {
for(re int i=head[x];i;i=e[i].nxt)
if(dep[e[i].v]>dep[x]&&son[x]!=e[i].v) dsu(e[i].v,0);
if(son[x]) dsu(son[x],1);
S=son[x],calc(x,1),S=0;
for(re int i=1;i<=m;i++) {
int g=ask(find(mx[x]+q[i]));
Ans[i]=max(Ans[i],g);
}
if(!k) calc(x,-1);
}
int main() {
n=read();
for(re int x,y,w,i=1;i<n;++i)
x=read(),y=read(),w=read(),add(x,y,w),add(y,x,w);
m=read();for(re int i=1;i<=m;i++) scanf("%lld",&q[i]);
dfs(1,0);rt=1;
for(re int i=2;i<=n;i++) if(pre[i]>pre[rt]) rt=i;
pre[rt]=0;dfs(rt,0);Rt=1;
for(re int i=1;i<=n;i++) mx[i]=pre[i];
for(re int i=2;i<=n;i++) if(pre[i]>pre[Rt]) Rt=i;
pre[Rt]=0;dfs(Rt,0);
for(re int i=1;i<=n;i++) mx[i]=max(mx[i],pre[i]);
rt=1;for(re int i=2;i<=n;i++) if(mx[i]<mx[rt]) rt=i;
dep[rt]=1;dfs1(rt);
for(re int i=1;i<=n;i++) c[i]=mx[i];
std::sort(c+1,c+n+1);sz=std::unique(c+1,c+n+1)-c-1;
for(re int i=1;i<=n;i++) pos[i]=find(mx[i]);
dsu(rt,1);for(re int i=1;i<=m;i++) printf("%d\n",Ans[i]);
return 0;
}
【CF516D】Drazil and Morning Exercise的更多相关文章
- 「CF516D」 Drazil and Morning Exercise
「CF516D」 Drazil and Morning Exercise 传送门 这个 \(f_i\) 显然可以通过树形 \(\texttt{DP}\) 直接求. 然后看到这种差值问题感觉就可以二分转 ...
- 【Cf #292 D】Drazil and Morning Exercise(树的直径,树上差分)
有一个经典的问题存在于这个子问题里,就是求出每个点到其他点的最远距离. 这个问题和树的直径有很大的关系,因为事实上距离每个点最远的点一定是直径的两个端点.所以我们可以很容易地进行$3$遍$Dfs$就可 ...
- 【UFLDL】Exercise: Convolutional Neural Network
这个exercise需要完成cnn中的forward pass,cost,error和gradient的计算.需要弄清楚每一层的以上四个步骤的原理,并且要充分利用matlab的矩阵运算.大概把过程总结 ...
- 【原】Coursera—Andrew Ng机器学习—编程作业 Programming Exercise 1 线性回归
作业说明 Exercise 1,Week 2,使用Octave实现线性回归模型.数据集 ex1data1.txt ,ex1data2.txt 单变量线性回归必须实现,实现代价函数计算Computin ...
- 【codeforces 515D】Drazil and Tiles
[题目链接]:http://codeforces.com/contest/515/problem/D [题意] 给你一个n*m的格子; 然后让你用1*2的长方形去填格子的空缺; 如果有填满的方案且方案 ...
- 【codeforces 515C】Drazil and Factorial
[题目链接]:http://codeforces.com/contest/515/problem/C [题意] 定义f(n)=n这个数各个位置上的数的阶乘的乘积; 给你a; 让你另外求一个不含0和1的 ...
- 【codeforces 515B】Drazil and His Happy Friends
[题目链接]:http://codeforces.com/contest/515/problem/B [题意] 第i天选择第i%n个男生,第i%m个女生,让他们一起去吃饭; 只要这一对中有一个人是开心 ...
- 【codeforces 515A】Drazil and Date
[题目链接]:http://codeforces.com/contest/515/problem/A [题意] 每次只能走到相邻的四个格子中的一个; 告诉你最后走到了(a,b)走了多少步->s ...
- Python高手之路【三】python基础之函数
基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...
随机推荐
- 四:RF框架appium工具之xpath定位
XPATH定位方法具体的学会,还是在今年1月份,以前运用的都不熟练. 这个定位神器是一定要掌握的,不然有你抓狂的时候. 第一要掌握它的书写格式,这个好上手. 第二要掌握它的具体用法.这个就要多练习了, ...
- 浅谈学习selenium的一些知识点的总结
学习自动化测试,先得学习一门语言.自动化对语言要求掌握的程度不深,但必须得会基本的入门语法. 我学习的是python2,简单,易懂,上手快. 每天敲就是了. 我的学习路径是: 先学习一段时间pytho ...
- Vmware ESXi安装群晖Synology DSM 5.x
简介 在Vmware ESXI中安装群晖Synology DSM 5.0 (4528) 文件准备 Vmware ESXi用户安装需要的文件 NB_x64_5032_DSM_50-4528_Xpenol ...
- Hibernate 和 JPA 注解
转载请注明:Hibernate 和 JPA 注解 | 言曌博客 1.@Entity(name="EntityName") 必须, name为可选,对应数据库中一的个表 2.@Tab ...
- VMware Pro v14.1.1 官方版本及激活密钥
热门虚拟机软件VMware Workstation Pro现已更新至14.1.1,14.0主要更新了诸多客户机操作系统版本,此外全面兼容Wind10创建者更新.12.0之后属于大型更新,专门为Win1 ...
- Day 18 :面向对象[基础,继承,组合]类的增删改查
有的人说,编程有3种范式: 1.面向过程:就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了. 2.面向函数:面向函数是面向过程的升级版,也就是把每个 ...
- [BOI2009]Radio Transmission 无线传输
题目描述 给你一个字符串,它是由某个字符串不断自我连接形成的. 但是这个字符串是不确定的,现在只想知道它的最短长度是多少. 输入输出格式 输入格式: 第一行给出字符串的长度,1 < L ≤ 1, ...
- python接口自动化(put请求)
python接口自动化(put请求) 一.put请求的作用:更新资源 二.应用 导包:import requests 调用requests.put()方法 参数有URL.data.headers,方法 ...
- 随笔记录 误删boot恢复 2019.8.7
系统还原: 1. 2. 3. 4. 5.进入硬盘 6.挂载光盘,安装恢复boot 7.安装grub2 8.重建grub.cfg文件
- Class类的作用?生成Class对象的方法有哪些?
Class类是Java 反射机制的起源和入口,用于获取与类相关的各种信息,提供了获取类信息的相关方法.Class类继承自Object类 Class类是所有类的共同的图纸.每个类有自己的对象,好比图纸和 ...