【BZOJ4071】八邻旁之桥(线段树)

题面

BZOJ权限题,洛谷链接

题解

既然\(k<=2\)

那么,突破口就在这里

分类讨论

①\(k=1\)

这。。。不就是中位数吗。。。。

直接把所有起点重点排个序,

算下中位数就行啦

②\(k=2\)

似乎不好搞了

orz ZSY Dalao

我太弱了

我就是一个Vegetable Chicken

ZSY看一眼就会做

补充:ZSY大佬提醒我,Bridge我写错了

所以:#define Brige Bridge

首先,我们来看一看,如果有两座桥,

一个人会怎么动呢?

如果桥在他所移动的横向区间内

那么,一定会过这座桥,距离为\(dis(Qi-Ti)+1\)

如果,没有桥在他的区间内

他就要先走到桥,再从桥走过来

此时距离为\(abs(Qi-Brige)+abs(Ti-Brige)+1\)

这个东西再结合图像化个简

等于\(2abs(\frac{Qi+Ti}{2}-Brige)+1\)

所以,这个人走的桥一定是离\(\frac{Qi+Ti}{2}\)较近的桥

因此,把所有人按照\(\frac{Qi+Ti}{2}\)排序之后

开始枚举在哪个位置割开

然后左边的都走左边的桥

右边的都走右边的桥

拆成了两边之后就是\(k=1\)的情况了

但是因为是动态维护区间的中位数

所以要找个东西来维护

权值线段树,平衡树都是可以的

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<set>
  8. #include<map>
  9. #include<vector>
  10. #include<queue>
  11. using namespace std;
  12. #define ll long long
  13. #define MAX 250000
  14. #define lson (now<<1)
  15. #define rson (now<<1|1)
  16. inline int read()
  17. {
  18. int x=0,t=1;char ch=getchar();
  19. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  20. if(ch=='-')t=-1,ch=getchar();
  21. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  22. return x*t;
  23. }
  24. struct Node{int a,b;}w[MAX];
  25. bool operator<(Node a,Node b){return a.a+a.b<b.a+b.b;}
  26. int cnt;
  27. long long ans;
  28. int K,n,a[MAX],b[MAX],S[MAX],top;
  29. struct SegMentTree
  30. {
  31. struct node
  32. {
  33. int size;ll sum;
  34. }t[MAX<<2];
  35. int Kth(int now,int l,int r,int k)
  36. {
  37. if(l==r)return l;
  38. int mid=(l+r)>>1;
  39. if(k<=t[lson].size)return Kth(lson,l,mid,k);
  40. else return Kth(rson,mid+1,r,k-t[lson].size);
  41. }
  42. void Modify(int now,int l,int r,int pos,int ww)
  43. {
  44. t[now].size+=ww;t[now].sum+=1ll*ww*S[pos];
  45. if(l==r)return;
  46. int mid=(l+r)>>1;
  47. if(pos<=mid)Modify(lson,l,mid,pos,ww);
  48. else Modify(rson,mid+1,r,pos,ww);
  49. }
  50. ll QueryV(int now,int l,int r,int al,int ar)
  51. {
  52. if(al<=l&&r<=ar)return t[now].sum;
  53. int mid=(l+r)>>1;ll ret=0;
  54. if(al<=mid)ret+=QueryV(lson,l,mid,al,ar);
  55. if(ar>mid)ret+=QueryV(rson,mid+1,r,al,ar);
  56. return ret;
  57. }
  58. int QueryS(int now,int l,int r,int al,int ar)
  59. {
  60. if(al<=l&&r<=ar)return t[now].size;
  61. int mid=(l+r)>>1,ret=0;
  62. if(al<=mid)ret+=QueryS(lson,l,mid,al,ar);
  63. if(ar>mid)ret+=QueryS(rson,mid+1,r,al,ar);
  64. return ret;
  65. }
  66. }T[2];
  67. int main()
  68. {
  69. K=read();n=read();
  70. char ch[2];
  71. if(K==1)
  72. {
  73. int tot=0;
  74. for(int i=1;i<=n;++i)
  75. {
  76. scanf("%s",ch);int p=ch[0]-'A';
  77. int s=read();
  78. scanf("%s",ch);int q=ch[0]-'A';
  79. int t=read();
  80. if(p==q){ans+=abs(s-t);continue;}
  81. else if(p==1)swap(s,t);
  82. ++tot;a[tot]=s;b[tot]=t;S[++top]=s;S[++top]=t;
  83. }
  84. sort(&S[1],&S[top+1]);
  85. int G=S[top/2];
  86. for(int i=1;i<=top;++i)ans+=abs(G-S[i]);
  87. printf("%lld\n",ans+tot);
  88. return 0;
  89. }
  90. for(int i=1;i<=n;++i)
  91. {
  92. scanf("%s",ch);int p=ch[0]-'A';
  93. int s=read();
  94. scanf("%s",ch);int q=ch[0]-'A';
  95. int t=read();
  96. if(p==q){ans+=abs(s-t);continue;}
  97. ans++;S[++top]=s;S[++top]=t;
  98. if(s>t)swap(s,t);
  99. w[++cnt]=(Node){s,t};
  100. }
  101. if(!cnt){printf("%lld\n",ans);return 0;}
  102. sort(&w[1],&w[cnt+1]);
  103. sort(&S[1],&S[top+1]);
  104. top=unique(&S[1],&S[top+1])-S-1;
  105. for(int i=1;i<=cnt;++i)
  106. {
  107. w[i].a=lower_bound(&S[1],&S[top+1],w[i].a)-S;
  108. w[i].b=lower_bound(&S[1],&S[top+1],w[i].b)-S;
  109. T[1].Modify(1,1,top,w[i].a,1);
  110. T[1].Modify(1,1,top,w[i].b,1);
  111. }
  112. long long sum=1e18;
  113. for(int i=1;i<=cnt;++i)
  114. {
  115. T[0].Modify(1,1,top,w[i].a,1);
  116. T[0].Modify(1,1,top,w[i].b,1);
  117. T[1].Modify(1,1,top,w[i].a,-1);
  118. T[1].Modify(1,1,top,w[i].b,-1);
  119. int p1=T[0].Kth(1,1,top,i);//找中位数
  120. int p2=T[1].Kth(1,1,top,cnt-i);
  121. long long D0=0;
  122. D0+=1ll*T[0].QueryS(1,1,top,1,p1)*S[p1]-T[0].QueryV(1,1,top,1,p1);
  123. D0+=T[0].QueryV(1,1,top,p1,top)-1ll*T[0].QueryS(1,1,top,p1,top)*S[p1];
  124. long long D1=0;
  125. D1+=1ll*T[1].QueryS(1,1,top,1,p2)*S[p2]-T[1].QueryV(1,1,top,1,p2);
  126. D1+=T[1].QueryV(1,1,top,p2,top)-1ll*T[1].QueryS(1,1,top,p2,top)*S[p2];
  127. sum=min(sum,D0+D1);
  128. }
  129. printf("%lld\n",ans+sum);
  130. return 0;
  131. }

【BZOJ4071】八邻旁之桥(线段树)的更多相关文章

  1. 洛谷 P3644 [APIO2015]八邻旁之桥 解题报告

    P3644 [APIO2015]八邻旁之桥 题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域\(A\)和区域\(B\). 每一块区域沿着河岸都建了恰好\(1000000001\)栋的建筑 ...

  2. [APIO2015]八邻旁之桥——非旋转treap

    题目链接: [APIO2015]八邻旁之桥 对于$k=1$的情况: 对于起点和终点在同侧的直接计入答案:对于不在同侧的,可以发现答案就是所有点坐标与桥坐标的差之和+起点与终点不在同一侧的人数. 将所有 ...

  3. [luoguP3644] [APIO2015]八邻旁之桥(权值线段树)

    传送门 首先如果起点终点都在同一侧可以直接处理,如果需要过桥答案再加1 对于k等于1的情况 桥的坐标为x的话,a和b为起点和终点坐标 $ans=\sum_{1}^{n} abs(a_{i}-x)+ab ...

  4. [BZOJ4071][APIO2015]八邻旁之桥

    BZOJ(这题是BZOJ权限题,有权限号的就去看看吧) Luogu(良心洛谷) 题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域\(A\)和区域\(B\). 每一块区域沿着河岸都建了恰好 ...

  5. [APIO2015]八邻旁之桥

    题面在这里 sol 这是一个\(Splay\)的题解 首先,如果一个人的家和办公室在同一侧,我们可以直接预处理; 如果不在同一侧,也可以加上1(当然要过桥啦) 当k==1时 我们设桥的位置为\(pos ...

  6. 题解【luoguP3644 [APIO2015]八邻旁之桥】

    题目链接 题解 家和公司在同侧 简单,直接预处理掉 若 \(k=1\) 取所有的居民的\(\frac{家坐标+公司坐标}{2}\)的所有坐标的正中间建一座桥,使所有居民到的距离最小. 实现方法:线段树 ...

  7. APIO2015 八邻旁之桥/巴邻旁之桥

    题目描述: bz luogu 题解: 贪心+权值线段树. $K=1$的时候,答案为$\sum |x-l| + |x-r|$,所以所有端点排序后取中位数即可. $K=2$的时候,一定是左边的一些走左边的 ...

  8. 洛谷 P3644 [APIO2015]八邻旁之桥(对顶堆维护中位数)

    题面传送门 题意: 一条河将大地分为 \(A,B\) 两个部分.两部分均可视为一根数轴. 有 \(n\) 名工人,第 \(i\) 名的家在 \(x_i\) 区域的 \(a_i\) 位置,公司在 \(y ...

  9. 【BZOJ4071】[Apio2015]巴邻旁之桥 Treap

    [BZOJ4071][Apio2015]巴邻旁之桥 Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 ...

随机推荐

  1. 读书共享 Primer Plus C-part 12

    第十四章 结构和其他数据形式 1.关于上struct与union 的区别 #include<stdio.h> typedef union Book_u { int pags; int mo ...

  2. UITableView!别再用代码计算行高了(一)

    你还在用代码去计算行高吗?你不感觉那种方式很low吗?从今天起,试着做些改变吧! 别给我讲你喜欢写代码的感觉,你就是要用代码去计算行高,那我这篇文章不适合你. 在讲解复杂内容之前,还是先学习简单的内容 ...

  3. xBIM WeXplorer xViewer的导航,相机、剖切、隐藏 等操作

    目录 基础 xBIM WeXplorer 简要介绍 xBIM WeXplorer xViewer 基本应用 xBIM WeXplorer xViewer 浏览器检查 xBIM WeXplorer xV ...

  4. Activt工作流数据库对应表的作用

    1.资源库流程规则表 1)       act_re_deployment 部署信息表 2)       act_re_model                流程设计模型部署表 3)       ...

  5. length()方法,length属性和size()的方法的区别

    length()方法,length属性和size()的方法的区别: length()方法是针对字符串来说的,要求一个字符串的长度就要用到它的length()方法: length属性是针对Java中的数 ...

  6. PAT乙级 1034

    思路:是个水题,但是有坑.不能被题目忽悠了,题目保证正确的输出中没有超过整型范围的整数. 它只是保证结果不超出int,但是我们在运算过程中的乘法可能会超出int,直接把所有int改成long long ...

  7. HDU - 1907 John 反Nimm博弈

    思路: 注意与Nimm博弈的区别,谁拿完谁输! 先手必胜的条件: 1.  每一个小游戏都只剩一个石子了,且SG = 0. 2. 至少有一堆石子数大于1,且SG不等于0 证明:1. 你和对手都只有一种选 ...

  8. nginx80端口被占用,启动失败。

    mac自带的apache占用了80端口,导致nginx服务器不能启动.这个问题是怎么解决的,目前还是不清楚. apache占用端口,使用命令进行关闭: apachectl  -k  stop,然后重启 ...

  9. Vmware下centos与windows能ping通并能上网

    1.桥接模式 2.NAT模式 3.Host-Only模式 1.桥接模式 vim /etc/udev/rules.d/70-persistent-net.rules 与/etc/sysconfig/ne ...

  10. mongodb: Remote server has closed the connection

    <?php function getMongoClient($seeds = "", $options = array(), $retry = 3) { try { retu ...