uoj#276. 【清华集训2016】汽水(分数规划+点分治)
没想到点分治那一层……
首先不难发现这是个分数规划,先把所有的边长减去\(k\),二分答案,设为\(mid\),就是要求路径平均值\(ans\in[-mid,mid]\)
先来考虑\(ans\in[0,mid]\)的的情况。我们考虑点分治,记下所有从根节点延伸下去的链,长度记为\(len\),边数为\(dep\),属于那一颗子树为\(bl\),先添加一条链\((0,0,0)\),那么两条链合法当且仅当\(\frac{len_i+len_j}{dep_i+dep_j}\in [0,mid]\),即有\(len_i+len_j\geq 0\)且\(len_i-mid\times dep_i+len_j-mid\times dep_j\leq 0\),那么把所有的链按长度排序,当从左到右扫描\(j\)的时候,可行的\(j\)的左端点一定是不断左移的,所以可以拿两个指针扫。不过要注意两条链不能在同一棵子树内,所以当\(j\)不断左移时,要记录属于两个不同子树的最大值才行
然后这里有一个小\(trick\),按上面双指针移的话可能会出现某一个最大值就是\(i\)的情况,要分类讨论很麻烦。我们可以把链按照长度的正负分为两类,那么上面那种情况可以把指针在长度为正的里面左移,在长度为负的里面右移,那么长度为负的里面的每一条链都可以用来更新最大值,而长度为正的只要在判断完之后再更新就可以了
\(ans\in[-mid,0]\)同理,不多讲了
//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define fi first
#define se second
#define inf 1e18
#define pi pair<ll,int>
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*pp=buf,*ppp=buf;
inline char getc(){return pp==ppp&&(ppp=(pp=buf)+fread(buf,1,1<<21,stdin),pp==ppp)?EOF:*pp++;}
ll read(){
R ll res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R ll x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e5+5;
struct eg{int v,nx;ll w;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v,R ll w){e[++tot]={v,head[u],w},head[u]=tot;}
struct node{
int dep;ll dis;int bl;
node(int dep=0,ll dis=0,int bl=0):dep(dep),dis(dis),bl(bl){}
inline bool operator <(const node &b)const{return dis<b.dis;}
}p1[N],p2[N];ll k,w,ans=inf;pi A,B;
int sz[N],son[N],vis[N];
int n,rt,size,u,v,t1,t2;
void findrt(int u,int fa){
sz[u]=1,son[u]=0;
go(u)if(v!=fa&&!vis[v]){
findrt(v,u),sz[u]+=sz[v];
son[u]=max(son[u],sz[v]);
}son[u]=max(son[u],size-sz[u]);
if(son[u]<son[rt])rt=u;
}
void dfs(int u,int fa,int dep,ll dis,int bl){
(dis>=0?(p1[++t1]):(p2[++t2]))=node(dep,dis,bl);
go(u)if(v!=fa&&!vis[v])dfs(v,u,dep+1,dis+e[i].w,bl);
}
void cmin(pi x){
if(x.fi<A.fi){
if(x.se!=A.se)B=A;
A=x;
}else if(x.fi<B.fi&&x.se!=A.se)B=x;
}
void cmax(pi x){
if(x.fi>A.fi){
if(x.se!=A.se)B=A;
A=x;
}else if(x.fi>B.fi&&x.se!=A.se)B=x;
}
bool ck(ll val){
A=B=pi(inf,0);
for(R int i=1,j=t2;i<=t1;++i){
while(p1[i].dis+p2[j].dis>=0&&j){
cmin(pi(p2[j].dis-p2[j].dep*val,p2[j].bl)),--j;
}if((A.se==p1[i].bl?B.fi:A.fi)+p1[i].dis-p1[i].dep*val<0)return 1;
cmin(pi(p1[i].dis-p1[i].dep*val,p1[i].bl));
}
A=B=pi(-inf,0);
for(R int i=t2,j=1;i;--i){
while(p2[i].dis+p1[j].dis<0&&j<=t1){
cmax(pi(p1[j].dis+p1[j].dep*val,p1[j].bl)),++j;
}if((A.se==p2[i].bl?B.fi:A.fi)+p2[i].dis+p2[i].dep*val>0)return 1;
cmax(pi(p2[i].dis+p2[i].dep*val,p2[i].bl));
}
return 0;
}
void solve(int u){
vis[u]=1;int dsize=size;
t1=t2=0;p1[++t1]=node(0,0,u);
go(u)if(!vis[v])dfs(v,u,1,e[i].w,v);
sort(p1+1,p1+t1+1),sort(p2+1,p2+t2+1);
ll l=1,r=ans-1,mid;
while(l<=r){
mid=(l+r)>>1;
if(ck(mid))r=mid-1;
else l=mid+1;
}ans=min(ans,l);
go(u)if(!vis[v]){
size=(sz[u]>sz[v]?sz[v]:dsize-sz[u]);
rt=0,findrt(v,0),solve(rt);
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),k=read();
fp(i,1,n-1)u=read(),v=read(),w=read()-k,add(u,v,w),add(v,u,w),ans=min(ans,abs(w)+1);
son[0]=n+1,rt=0,size=n;
findrt(1,0),solve(rt);
printf("%lld\n",ans-1);
return 0;
}
uoj#276. 【清华集训2016】汽水(分数规划+点分治)的更多相关文章
- [UOJ#276][清华集训2016]汽水[分数规划+点分治]
题意 给定一棵 \(n\) 个点的树,给定 \(k\) ,求 \(|\frac{\sum w(路径长度)}{t(路径边数)}-k|\)的最小值. \(n\leq 5\times 10^5,k\leq ...
- [UOJ#274][清华集训2016]温暖会指引我们前行
[UOJ#274][清华集训2016]温暖会指引我们前行 试题描述 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出无助的哀嚎 “冻死宝宝了!” 这时 远处的天边出现了一 ...
- BZOJ.4738.[清华集训2016]汽水(点分治 分数规划)
BZOJ UOJ 记\(val_i\)是每条边的边权,\(s\)是边权和,\(t\)是经过边数,\(k\)是给定的\(k\). 在点分治的时候二分答案\(x\),设\(|\frac st-k|=x\) ...
- BZOJ 4732 UOJ #268 [清华集训2016]数据交互 (树链剖分、线段树)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4732 (UOJ) http://uoj.ac/problem/268 题解 ...
- UOJ276 [清华集训2016] 汽水 【二分答案】【点分治】【树状数组】
题目分析: 这种乱七八糟的题目一看就是点分治,答案有单调性,所以还可以二分答案. 我们每次二分的时候考虑答案会不会大于等于某个值,注意到系数$k$是无意义的,因为我们可以通过转化使得$k=0$. 合并 ...
- 并不对劲的uoj276. [清华集训2016]汽水
想要很对劲的讲解,请点击这里 题目大意 有一棵\(n\)(\(n\leq 50000\))个节点的树,有边权 求一条路径使该路径的边权平均值最接近给出的一个数\(k\) 输出边权平均值下取整的整数部分 ...
- [UOJ#276]【清华集训2016】汽水
[UOJ#276][清华集训2016]汽水 试题描述 牛牛来到了一个盛产汽水的国度旅行. 这个国度的地图上有 \(n\) 个城市,这些城市之间用 \(n−1\) 条道路连接,任意两个城市之间,都存在一 ...
- UOJ 275. 【清华集训2016】组合数问题
UOJ 275. [清华集训2016]组合数问题 组合数 $C_n^m $表示的是从 \(n\) 个物品中选出 \(m\) 个物品的方案数.举个例子,从$ (1,2,3)(1,2,3)$ 三个物品中选 ...
- UOJ #269. 【清华集训2016】如何优雅地求和
UOJ #269. [清华集训2016]如何优雅地求和 题目链接 给定一个\(m\)次多项式\(f(x)\)的\(m+1\)个点值:\(f(0)\)到\(f(m)\). 然后求: \[ Q(f,n,x ...
- UOJ #274. 【清华集训2016】温暖会指引我们前行 [lct]
#274. [清华集训2016]温暖会指引我们前行 题意比较巧妙 裸lct维护最大生成树 #include <iostream> #include <cstdio> #incl ...
随机推荐
- Lombok引入简化Java代码
转载 http://t.cn/RS0UdrX Lombok简介 如Github上项目介绍所言,Lombok项目通过添加“处理程序”,使java成为一种更为简单的语言.作为一个Old Java Deve ...
- 九度OJ 1115:数字求和 (基础题)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2396 解决:1507 题目描述: 给定一个正整数a,以及另外的5个正整数,问题是:这5个整数中,小于a的整数的和是多少? 输入: 输入一行 ...
- android实现跑马灯效果
第一步:新建一个新项目,MarqueeTextView 首先为了观察到跑马灯效果,将要显示的文字极可能 写长.在strings.xml目录里面将 <string name="hello ...
- 一起来学linux:磁盘与文件系统:
对于文件系统来说,windows上最长用的就是FAT32和NTFS.在Linux上时候用的是Ext2.在linux中,文件权限与文件属性这两部分会被存储在不同的块,权限与权限放置到inode中,实际数 ...
- 稳定币GUSD的优劣势分析
在币圈,有人乘着牛市东风一夜暴富,也有人不幸赶上熊市倾家荡产,涨跌大起大落是币圈的常态,在如此不稳定的币市,投资者们都想寻求一些稳定.接着,稳定币诞生了. 2018年下半年,稳定币引起了各路投资者的高 ...
- (linux)idr(integer ID management)机制
最近研究进程间通信,遇到了idr相关的函数,为了扫清障碍,先研究了linux的idr机制. IDR(integer ID management)的要完成的任务是给要管理的对象分配一个唯一的ID,于 ...
- UVA1635 Irrelevant Elements —— 唯一分解定理 + 二项式定理
题目链接:https://vjudge.net/problem/UVA-1635 (紫书320) 题解: 1.根据二项式定理, 可得递推公式: C(n,k) = (n-k+1)/k * C(n, k- ...
- 【C/C++】产生随机数
#include<iostream> #include<Ctime> #include<Cstdlib> using namespace std; //产生n个st ...
- Java中的final和static
final final可以用在类.方法.变量上. 1.final用在类上,表明当前类它不能被继承,没有子类. 2.final用在方法上,表明当前方法不能被override,不能被重写. 3.final ...
- P2383 狗哥玩木棒
题目背景 狗哥又趁着语文课干些无聊的事了... 题目描述 现给出一些木棒长度,那么狗哥能否用给出的木棒(木棒全用完)组成一个正方形呢? 输入输出格式 输入格式: 输入文件中的第一行是一个整数n表示测试 ...