BZOJ
UOJ


记\(val_i\)是每条边的边权,\(s\)是边权和,\(t\)是经过边数,\(k\)是给定的\(k\)。
在点分治的时候二分答案\(x\),设\(|\frac st-k|=x\),判断是否还能满足\(|\frac st-k|<x\)。
因为是绝对值,分两种情况:

  1. \(\frac st-k\geq 0\to \sum val_i-k\geq 0\),
    判断是否有\(\frac st-k< x\to\quad s-t*k<t*x\to\quad\sum val_i-k<t*x\)。
  2. \(\frac st-k<0\to\sum val_i-k<0\),
    判断是否有\(\frac st-k>-x\to\quad s-t*k>-t*x\to\quad \sum val_i-k>-t*x\)

先对每条边的边权\(val_i\)减掉一个\(k\)。
以第一种情况为例,就是求是否存在两条路径\(i,j\),使得\(s_i+s_j\geq 0\),且\(s_i+s_j<t_i*x+t_j*x\)。
把\(DFS\)得到的子树路径信息存一个三元组\((s,t,anc)\),表示一条路径的权值和、边数、这条路径来自哪棵子树(两条路径拼起来的时候不能来自同一棵子树)。
然后把所有三元组按\(s\)从小到大排序。那从小到大枚举\(i\),第一个满足\(s_i+s_j\geq 0\)的\(j\)的位置一定是单调递减的,\(j\)后面(\(i\)之前)的路径都满足。
所以维护两个\(pair\),表示两个\(s_k-t_k*x\)最小的、来自不同子树的三元组\(A,B\)。找到第一个\(s_p>0\)的位置\(p\),令\(i=p,j=p-1\),然后随着\(i\)的枚举,更新一下\(A,B\),然后\(j\)也不断往前移动顺便更新\(A,B\)就可以了。每次对于\(i\),就把\(A,B\)做\(k\),与\(i\)组合一下看是否可以满足\(s_k-t_k*x<t_i*x-s_i\)。
具体看代码吧,

有两种情况就二分\(x\)的时候,用两个\(check\)判断\(x\)(\(\frac st -k\geq 0\))和\(-x\)(\(\frac st-k<0\))是否有一个可行就行了。

都是抄的一份代码 常数差距怎么就那么大呢


//6952kb    6680ms
#include <cstdio>
#include <cctype>
#include <algorithm>
#define mp std::make_pair
#define pr std::pair<LL,int>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=5e4+5;
const LL INF=1ll<<60;int cnt,Enum,H[N],nxt[N<<1],to[N<<1],Min,root,sz[N];
LL Ans,len[N<<1];
bool vis[N];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Node
{LL s; int t,anc;inline bool operator <(const Node &x)const{return s<x.s;}
}A[N];inline int read()
{int now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-48,c=gc());return now;
}
inline LL readll()
{LL now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-48,c=gc());return now;
}
inline void AE(LL w,int u,int v)
{Ans=std::min(Ans,std::abs(w));//abs!!!to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, len[Enum]=w;to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, len[Enum]=w;
}
void FindRoot(int x,int fa,int tot)
{int mx=0; sz[x]=1;for(int i=H[x],v; i; i=nxt[i])if(!vis[v=to[i]]&&v!=fa)FindRoot(v,x,tot), sz[x]+=sz[v], sz[v]>mx&&(mx=sz[v]);mx=std::max(mx,tot-sz[x]);if(mx<Min) Min=mx, root=x;
}
void DFS(int x,int fa,LL s,int dep,int anc)
{A[++cnt]=(Node){s,dep,anc};for(int i=H[x],v; i; i=nxt[i])if(!vis[v=to[i]] && v!=fa) DFS(v,x,s+len[i],dep+1,anc);
}
inline void Upd(pr &x,pr &y,pr now)
{if(now.first<y.first){if(now.first<x.first){if(now.second!=x.second) y=x;x=now;}else if(now.second!=x.second) y=now;}
}
bool Check1(LL k,int pos,int cnt)
{pr x(INF,0),y(INF,0); A[0].s=-INF;for(int i=pos,j=pos-1; i<=cnt; ++i){while(A[i].s+A[j].s>=0) Upd(x,y,mp(A[j].s-k*A[j].t,A[j].anc)), --j;if((x.second==A[i].anc?y.first:x.first)+A[i].s<k*A[i].t) return 1;Upd(x,y,mp(A[i].s-k*A[i].t,A[i].anc));}return 0;
}
bool Check2(LL k,int pos,int cnt)
{//s>-tx -> -s<txpr x(INF,0),y(INF,0); A[cnt+1].s=INF;for(int i=pos-1,j=pos; i; --i){while(A[i].s+A[j].s<0) Upd(x,y,mp(-A[j].s-k*A[j].t,A[j].anc)), ++j;if((x.second==A[i].anc?y.first:x.first)-A[i].s<k*A[i].t) return 1;Upd(x,y,mp(-A[i].s-k*A[i].t,A[i].anc));}return 0;
}
void Solve(int x)
{vis[x]=1, A[cnt=1]=(Node){0,0,0};for(int i=H[x],v; i; i=nxt[i])if(!vis[v=to[i]]) DFS(v,x,len[i],1,v);int p=1; std::sort(A+1,A+1+cnt), A[cnt+1].s=0;while(A[p].s<0) ++p;LL l=1,r=Ans,mid;//判断是否存在比Ans小的答案 范围是1~Ans!(UOJ数据真心强=-=)while(l<=r)if(Check1(mid=l+r>>1,p,cnt)||Check2(mid,p,cnt)) Ans=mid-1, r=mid-1;else l=mid+1;for(int i=H[x],v; i; i=nxt[i])if(!vis[v=to[i]]) Min=N, FindRoot(v,x,sz[v]), Solve(root);
}int main()
{const int n=read(); const LL K=readll();//readll!!Ans=INF;//在这 不能在Solve()前面 = = for(int i=1; i<n; ++i) AE(readll()-K,read(),read());Min=N, FindRoot(1,1,n), Solve(root);printf("%lld\n",Ans);return 0;
}

转载于:https://www.cnblogs.com/SovietPower/p/10322621.html

BZOJ.4738.[清华集训2016]汽水(点分治 分数规划)相关推荐

  1. UOJ276 [清华集训2016] 汽水 【二分答案】【点分治】【树状数组】

    题目分析: 这种乱七八糟的题目一看就是点分治,答案有单调性,所以还可以二分答案. 我们每次二分的时候考虑答案会不会大于等于某个值,注意到系数$k$是无意义的,因为我们可以通过转化使得$k=0$. 合并 ...

  2. UOJ #268 BZOJ 4732 [清华集训2016]数据交互 (树链剖分、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4732 (UOJ) http://uoj.ac/problem/268 题解 ...

  3. UOJ #277 BZOJ 4739 [清华集训2016]定向越野 (计算几何、最短路)

    手动博客搬家: 本文发表于20181208 14:39:01, 原地址https://blog.csdn.net/suncongbo/article/details/84891710 哇它居然显示出图 ...

  4. UOJ #274. 【清华集训2016】温暖会指引我们前行 [lct]

    #274. [清华集训2016]温暖会指引我们前行 题意比较巧妙 裸lct维护最大生成树 #include <iostream> #include <cstdio> #incl ...

  5. [清华集训2016]石家庄的工人阶级队伍比较坚强——三进制FWT

    题目链接: [清华集训2016]石家庄的工人阶级队伍比较坚强 题目大意:有$n=3^m$个人玩石头剪刀布,共$t$轮游戏,每轮每个人要和包括自己的所有人各进行$m$次石头剪刀布.每个人在$m$轮中的决 ...

  6. 【清华集训2016】数据交互

    [清华集训2016]数据交互 比较神的\(DDP\). 首先对于给出的一条链我们分两部分统计:\(lca\)以及其他部分. 我们设两个变量\(w_i,g_i\).一条路径的权值就是路径上所有点的\(w ...

  7. P6669 [清华集训2016] 组合数问题

    P6669 [清华集训2016] 组合数问题 题意: 给你n,m,k,问有多少对(i,j)满足K∣CijK|C_{i}^{j}K∣Cij​ (Cij是k的倍数C_{i}^{j}是k的倍数Cij​是k的 ...

  8. [清华集训2016]你的生命已如风中残烛——组合数学

    题目链接: [清华集训2016]你的生命已如风中残烛 题目大意:共有$m+1$张牌,其中有$n$张特殊牌,每张特殊牌有一个权值$w_{i}$表示取到这张牌能获得$w_{i}$次再抽牌的机会,保证$\s ...

  9. BZOJ 4732 UOJ #268 [清华集训2016]数据交互 (树链剖分、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4732 (UOJ) http://uoj.ac/problem/268 题解 ...

最新文章

  1. linux c glob使用(文件路径模式查找函数)
  2. GCC安装UBUNTU
  3. html dom 替换节点,从javascript dom文本节点替换
  4. POJ - 1469 COURSES (匈牙利算法入门题)
  5. (课程学习笔记)Python基础学习
  6. cocos2d-x游戏实例(24)-简易动作游戏(2)
  7. linux namespace 工具,Linux Namespace : 简介
  8. .bash_profile和.bashrc说明
  9. undefined reference to `cv::VideoCapture::VideoCapture()'
  10. 【AI视野·今日Robot 机器人论文速览 第四期】Wed, 9 Jun 2021
  11. pandas read_sql
  12. win32 api for .net
  13. 【BZOJ2164】采矿 树链剖分+线段树维护DP
  14. 69期-Java SE-004_循环、数组-001-002
  15. AndroidStudio中获得的VersionCode一直为1和VersionName一直为1.0
  16. 12个你值得拥有的虚拟科学实验APP、工具和资源
  17. ubuntu 多声卡设置 默认声卡 systemd自启动声卡设置
  18. www 53ff com劫持IE,广告网页图标常驻桌面,删了又来
  19. qpushbutton设置居中_在右侧对齐图标并将文本居中放置在QPushButton中
  20. ORA-01507错误

热门文章

  1. Codeforces 494Div3(ABCDJava编写)
  2. php pcntl 进程池_PHP 进程池与轮询调度算法实现多任务的示例代码
  3. H. Texas hold'em Poker(2019ICPC区域网络赛沈阳站)
  4. JAVA爬虫https_java爬虫问题一:解决使用htmlunit 时候ssl认证失败问题
  5. 隐藏ajax的调用地址,c# – ASP.NET jQuery Ajax调用代码隐藏方法
  6. python自媒体创作_做自媒体该做什么领域?
  7. db29.7时间格式化为时间到时分秒_python基础系列 | 示例讲解时间模块datetime
  8. Linux 服务器必备的安全设置,建议收藏!
  9. 疲劳容器的定义_疲劳分析基础
  10. 职业高中计算机英语教案,信息技术与中学英语整合课教学设计