题目分析:

这种乱七八糟的题目一看就是点分治,答案有单调性,所以还可以二分答案。

我们每次二分的时候考虑答案会不会大于等于某个值,注意到系数$k$是无意义的,因为我们可以通过转化使得$k=0$。

合并的过程相当于很多个向量,加起来后看斜率。

注意单个向量也要判定。

由于有了二分的答案$Ans$。判定变得简单多了,推一下。

令$(A,C)$是从一个点到重心的一个向量,$(B,D)$是从另一个点到重心的向量。其中$A$和$B$是重心到该点的路径权值和,$C$和$D$是经过的边数。

$-k \leq \frac{A+C}{B+D} \leq k \Rightarrow -k(B+D) \leq A+C \leq k(B+D)$.

进一步的$A+kB \geq -C-kD$且$A-kB \leq kD-C$。虽然有四元,但是顺序相互关联,所以实际只有两元,排序后树状数组就可以解决啦。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3
  4 typedef long long ll;
  5
  6 const int maxn = 50100;
  7
  8 ll k,md; int flag = 0,num,n,rnum;
  9 vector <pair<int,ll> > g[maxn];
 10 int arr[maxn],sz[maxn],imp[maxn],cnt[maxn];
 11 struct node{ll A;int B,pla;}op[maxn];
 12
 13 int cmp(node X,node Y){
 14     return -X.A-md*X.B < -Y.A-md*Y.B;
 15 }
 16
 17 struct Fenwick{
 18     int C[maxn];
 19     void Add(int now){
 20     while(now <= rnum){C[now] ++; now += (now&-now);}
 21     }
 22     int query(int now){
 23     int ans = 0;
 24     while(now){ans += C[now]; now -= (now&-now);}
 25     return ans;
 26     }
 27 }T1;
 28
 29 void read(){
 30     scanf("%d%lld",&n,&k);
 31     for(int i=1;i<n;i++){
 32     int x,y;long long v; scanf("%d%d%lld",&x,&y,&v); v -= k;
 33     g[x].push_back(make_pair(y,v)); g[y].push_back(make_pair(x,v));
 34     }
 35 }
 36
 37 void dfs1(int now,int fa,int dp){
 38     sz[now] = 1;imp[now] = 0;
 39     for(auto it : g[now]){
 40     if((arr[it.first] && arr[it.first] < dp) || fa == it.first) continue;
 41     dfs1(it.first,now,dp); sz[now] += sz[it.first];
 42     }
 43 }
 44
 45 int dfs2(int now,int fa,int dp,int ssz){
 46     int ans = 0;
 47     for(auto it : g[now]){
 48     if((arr[it.first] && arr[it.first] < dp) || fa == it.first) continue;
 49     int data = dfs2(it.first,now,dp,ssz);
 50     if(ans==0 || imp[ans] > imp[data])ans = data;
 51     imp[now] = max(sz[it.first],imp[now]);
 52     }
 53     imp[now] = max(imp[now],ssz-sz[now]);
 54     if(ans==0 || imp[ans] > imp[now]) ans = now;
 55     return ans;
 56 }
 57
 58 void dfs3(int now,int fa,int dp,int A,int B){
 59     for(auto it : g[now]){
 60     if(it.first == fa || (arr[it.first] && arr[it.first] < dp)) continue;
 61     op[++num] = (node){A+it.second,B+1,it.first};
 62     dfs3(it.first,now,dp,A+it.second,B+1);
 63     }
 64 }
 65
 66 long long lisan[maxn];
 67 void solve(int dr){
 68     rnum = num;
 69     for(int i=1;i<=num;i++){lisan[i] = -op[i].A+md*op[i].B;}
 70     sort(lisan+1,lisan+num+1);rnum = unique(lisan+1,lisan+num+1)-lisan-1;
 71     for(int i=1;i<=rnum;i++) T1.C[i]=0;
 72     for(int i=num,j=1;i>=1;i--){
 73     while(j <= num && (-op[j].A-md*op[j].B < op[i].A+md*op[i].B)){
 74         T1.Add(lower_bound(lisan+1,lisan+rnum+1,-op[j].A+md*op[j].B)-lisan);
 75         j++;
 76     }
 77     int ans=j-1-T1.query(upper_bound(lisan+1,lisan+rnum+1,op[i].A-md*op[i].B)-lisan-1);
 78     if(op[i].A-md*op[i].B < -op[i].A+md*op[i].B && j > i)ans--;
 79     if(dr == 1){
 80         if(ans - cnt[op[i].pla]){flag = 1;return;}
 81     }else{cnt[op[i].pla] = ans;}
 82     }
 83 }
 84
 85 void divide(int now,int dp,int lst,long long AA){
 86     dfs1(now,0,dp); int heavy = dfs2(now,0,dp,sz[now]);arr[heavy] = dp;
 87     for(auto it : g[heavy]){
 88     if(arr[it.first]&&arr[it.first]<dp) continue;
 89     divide(it.first,dp+1,heavy,it.second);
 90     if(flag == 1) return;
 91     }
 92     num = 0; dfs3(heavy,0,dp,0,0); sort(op+1,op+num+1,cmp);
 93     solve(1); num = 0;
 94     if(lst) {
 95     num = 0;dfs3(now,0,dp,AA,1);
 96     sort(op+1,op+num+1,cmp);
 97     for(int i=1;i<=num;i++) cnt[op[i].pla] = 0;
 98     solve(0);
 99     }
100 }
101
102 void work(){
103     long long l = 0,r = 1e13;
104     while(l < r){
105     md = (l+r)/2; flag = 0;
106     memset(arr,0,sizeof(arr));
107     divide(1,1,0,0);
108     if(flag) r = md; else l = md+1;
109     }
110     printf("%lld",l-1);
111 }
112
113 int main(){
114     read();
115     work();
116     return 0;
117 }

转载于:https://www.cnblogs.com/Menhera/p/9347630.html

UOJ276 [清华集训2016] 汽水 【二分答案】【点分治】【树状数组】相关推荐

  1. 洛谷P1527 [国家集训队] 矩阵乘法 [整体二分,二维树状数组]

    题目传送门 矩阵乘法 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入格式: 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N* ...

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

    BZOJ UOJ 记\(val_i\)是每条边的边权,\(s\)是边权和,\(t\)是经过边数,\(k\)是给定的\(k\). 在点分治的时候二分答案\(x\),设\(|\frac st-k|=x\) ...

  3. UOJ#271. 【清华集训2016】连通子树(虚树+倍增)

    传送门 题解: 注意到每种颜色个数比较少,于是建出虚树后暴力背包,用倍增维护一下虚链上的DP值即可. 所以说你只需要5个倍增数组和一些卡常技巧加上无数的小细节就可以通过这道题了. 不说了我去睡觉了. ...

  4. [bzoj2527][Poi2011]Meteors_整体二分_树状数组

    Meteors bzoj-2527 Poi-2011 题目大意:题目链接. 注释:略. 想法: 首先答案可以离线,且具有单调性. 这里的单调性就是随着时间的推移,每个国家收集的陨石数增加. 不难想到整 ...

  5. VK Cup 2012 Qualification Round 2 C. String Manipulation 1.0 线段树 or 树状数组+二分

    http://codeforces.com/problemset/problem/159/C 题意: 给你一个字符串s,给出一个数k,k倍的s串组成新串str.然后给出n个操作,每个操作对应着pi,c ...

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

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

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

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

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

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

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

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

最新文章

  1. python requests post 中文乱码问题
  2. 利用GoogleEarth影像打造Skyline MPT案例(转载)
  3. TCL通讯将刊行代表1.09亿股的台湾存托凭据
  4. CF1368G Shifting Dominoes(扫描线求矩阵的并集)
  5. 第73课 丑数 函数的应用
  6. iPhone SE 2渲染图再曝光:已加入浴霸摄像头豪华套餐
  7. react native进一步学习(NavigatorIOS 学习)
  8. 通用Makefile模板
  9. 安装和客户端证书颁发---puppet系列
  10. Oracle 分析函数row_number() over (partition by order by )
  11. 【Android每日一讲】2012.11.08 Android 多语系支持 -- Locale与Configuration
  12. js word 预览_个人电子简历模板在线编辑,大学生简历模板免费下载word 文档
  13. 图文并茂!CIC滤波器的FPGA实现
  14. 论文润色软件Stylewriter,whitesmoke,1check使用亲测
  15. 2018国赛数学建模B题一道工序代码
  16. JavaScript——模拟自动饮料机
  17. 苹果手机计算机按键会想关掉哪里,苹果手机,你不知道的隐藏功能
  18. Ubuntu16.04+Kinect2摄像头进行物体识别
  19. 【托福独立写作】ETS 官方新托福 185 个作文题库话题分类
  20. 如何构建全球实时音视频云及其海外网络传输优化

热门文章

  1. 使用windows crypto API加密解密
  2. 命令行关闭特定服务和调整服务启动方式
  3. winfrom下,如何实现类似QQ右下角弹出新闻
  4. linux如何查询一个文件夹大小,Linux下如何查看某个文件夹所占空间大小
  5. delay 芯片时序output_set_input_delay/set_output_delay
  6. java selenium_关于selenium的介绍
  7. ant如何形成时间轴和图库_如何让景观设计更具有逻辑性?
  8. 如何动态修改select的值_SQL成长记录02-SELECT语句
  9. jsonobject json对象里面_「jsonobject」用JSONObject解析和处理json数据 - seo实验室
  10. ChaiNext:大盘调整,主流币种还未稳住阻力位