APIO2015 八邻旁之桥/巴邻旁之桥
题目描述:
题解:
贪心+权值线段树。
$K=1$的时候,答案为$\sum |x-l| + |x-r|$,所以所有端点排序后取中位数即可。
$K=2$的时候,一定是左边的一些走左边的桥,右边的一些走右边的桥。
问题是按什么顺序排序。
答案是按线段中点排序。
原因是,对于河两岸的一对点和两座桥,选择的一定是离线段中点近的那个。
考虑如何快速计算答案,我们可以用权值线段树维护区间和与中位数。(当然也可以用平衡树)
代码:
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- typedef long long ll;
- const int N = 100050;
- const int M = 100*N;
- template<typename T>
- inline void read(T&x)
- {
- T f = 1,c = 0;char ch=getchar();
- while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
- while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
- x = f*c;
- }
- int K,n;
- ll ans;
- char op1[2],op2[2];
- struct Point
- {
- int l,r;
- Point(){}
- Point(int l,int r):l(l),r(r){}
- bool operator < (const Point&a)const{return l+r<a.l+a.r;}
- }p[N];
- int s[N<<1],tl;
- const int inf = 2000000001;
- struct segtree
- {
- int rt,tot,ls[M],rs[M],siz[M];
- ll sum[M];
- void insert(int l,int r,int&u,int qx)
- {
- if(!u)u=++tot;siz[u]++,sum[u]+=qx;
- if(l==r)return ;
- int mid = (l+r)>>1;
- if(qx<=mid)insert(l,mid,ls[u],qx);
- else insert(mid+1,r,rs[u],qx);
- }
- void erase(int l,int r,int u,int qx)
- {
- siz[u]--,sum[u]-=qx;if(l==r)return ;
- int mid = (l+r)>>1;
- if(qx<=mid)erase(l,mid,ls[u],qx);
- else erase(mid+1,r,rs[u],qx);
- }
- int query(int l,int r,int u,int rk)
- {
- if(!u)return -1;
- if(l==r)return l;
- int mid = (l+r)>>1;
- if(rk<=siz[ls[u]])return query(l,mid,ls[u],rk);
- else return query(mid+1,r,rs[u],rk-siz[ls[u]]);
- }
- ll query(int l,int r,int u,int ql,int qr)
- {
- if(!u||ql>qr)return 0;
- if(l==ql&&r==qr)return sum[u];
- int mid = (l+r)>>1;
- if(qr<=mid)return query(l,mid,ls[u],ql,qr);
- else if(ql>mid)return query(mid+1,r,rs[u],ql,qr);
- else return query(l,mid,ls[u],ql,mid)+query(mid+1,r,rs[u],mid+1,qr);
- }
- ll Query(int l,int r,int u,int ql,int qr)
- {
- if(!u||ql>qr)return 0;
- if(l==ql&&r==qr)return siz[u];
- int mid = (l+r)>>1;
- if(qr<=mid)return Query(l,mid,ls[u],ql,qr);
- else if(ql>mid)return Query(mid+1,r,rs[u],ql,qr);
- else return Query(l,mid,ls[u],ql,mid)+Query(mid+1,r,rs[u],mid+1,qr);
- }
- ll query(int siz)
- {
- int mid = query(0,inf,rt,siz);
- ll ql = query(0,inf,rt,0,mid-1),qr = query(0,inf,rt,mid+1,inf),tmp = (Query(0,inf,rt,mid+1,inf)-Query(0,inf,rt,0,mid-1));
- return qr-ql-tmp*mid;
- }
- }tr[2];
- int main()
- {
- // freopen("tt.in","r",stdin);
- read(K),read(n);
- for(int x,y,i=1;i<=n;i++)
- {
- scanf("%s",op1),read(x),scanf("%s",op2),read(y);
- if(x>y)swap(x,y);
- if(op1[0]==op2[0])
- {
- ans+=y-x;
- i--,n--;
- }else p[i]=Point(x,y);
- }
- ans+=n;
- if(!n)
- {
- printf("%lld\n",ans);
- return 0;
- }
- if(K==1)
- {
- for(int i=1;i<=n;i++)
- s[++tl]=p[i].l,s[++tl]=p[i].r;
- sort(s+1,s+tl+1);
- int mid = (s[tl/2]+s[tl/2+1])/2;
- int i;
- for(i=1;s[i]<=mid;i++)ans+=mid-s[i];
- for(;i<=tl;i++)ans+=s[i]-mid;
- printf("%lld\n",ans);
- return 0;
- }
- sort(p+1,p+1+n);
- for(int i=1;i<=n;i++)
- tr[1].insert(0,inf,tr[1].rt,p[i].l),tr[1].insert(0,inf,tr[1].rt,p[i].r);
- ll mx = 0x3f3f3f3f3f3f3f3fll;
- for(int i=1;i<=n;i++)
- {
- tr[0].insert(0,inf,tr[0].rt,p[i].l),tr[0].insert(0,inf,tr[0].rt,p[i].r);
- tr[1].erase (0,inf,tr[1].rt,p[i].l),tr[1].erase (0,inf,tr[1].rt,p[i].r);
- mx=min(mx,tr[0].query(i)+tr[1].query(n-i));
- }
- printf("%lld\n",ans+mx);
- return 0;
- }
APIO2015 八邻旁之桥/巴邻旁之桥的更多相关文章
- 洛谷 P3644 [APIO2015]八邻旁之桥 解题报告
P3644 [APIO2015]八邻旁之桥 题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域\(A\)和区域\(B\). 每一块区域沿着河岸都建了恰好\(1000000001\)栋的建筑 ...
- 【BZOJ4071】[Apio2015]巴邻旁之桥 Treap
[BZOJ4071][Apio2015]巴邻旁之桥 Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 ...
- [APIO2015]八邻旁之桥——非旋转treap
题目链接: [APIO2015]八邻旁之桥 对于$k=1$的情况: 对于起点和终点在同侧的直接计入答案:对于不在同侧的,可以发现答案就是所有点坐标与桥坐标的差之和+起点与终点不在同一侧的人数. 将所有 ...
- 4071: [Apio2015]巴邻旁之桥
Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 10000 ...
- [BZOJ4071][APIO2015]八邻旁之桥
BZOJ(这题是BZOJ权限题,有权限号的就去看看吧) Luogu(良心洛谷) 题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域\(A\)和区域\(B\). 每一块区域沿着河岸都建了恰好 ...
- BZOJ4071 & 洛谷3644 & UOJ112:[APIO2015]巴邻旁之桥——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4071 https://www.luogu.org/problemnew/show/P3644 ht ...
- [bzoj4071] [Apio2015]巴邻旁之桥
Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 10000 ...
- 【BZOJ4071】【APIO2015】巴邻旁之桥
题意: Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 1 ...
- Appium+python自动化(二十八)- 滑呀滑,滑到奈何桥喝碗孟婆汤 - 高级滑动(超详解)
简介 奈何桥上叹奈何,三生石前憾三生,彼岸花下非彼岸,奈何三生彼岸人. 相传过了鬼门关便上一条路叫黄泉路,路上盛开着只见花,不见叶的彼岸花.花叶生生两不见,相念相惜永相失,路尽头有一条河叫忘川河,河上 ...
随机推荐
- NeurIPS 2017 | QSGD: Communication-Efficient SGD via Gradient Quantization and Encoding
由于良好的可扩展性,随机梯度下降(SGD)的并行实现是最近研究的热点.实现并行化SGD的关键障碍就是节点间梯度更新时的高带宽开销.因此,研究者们提出了一些启发式的梯度压缩方法,使得节点间只传输压缩后的 ...
- Dubbo基础三之配置方式简述
Dubbo基础一之实战初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中,体验了两种配置方式一种注解一种xml.其中xml是在注解配置失败没有找到解决方法后选择xml替代体验的.那 ...
- SpringMVC--@RequestMapping注解标注方法解析
SpringMVC--@RequestMapping注解标注方法解析 本文是基于springboot进行源码追踪分析 问题 @RequestMapping注释的类及方法,Spring是何时,何种方式解 ...
- 一文了解如何源码编译Rainbond基础组件
Rainbond 主要由以下三个项目组成,参考官网详细 技术架构 业务端 Rainbond-UI 和 Rainbond-Console 合起来构成了业务层.业务层是前后端分离模式.UI是业务层的前端代 ...
- git忽略文件权限检查
如题 每个人本地设置不同 系统不同 环境不同 很有可能在团队开发的时候进行 不同文件权限的设置 但是如果大家都把这种权限的设置传上去 那么所有人的就都乱的 如果要去掉的话 第一步 进入这个项目的 ...
- [LeetCode]1221. 分割平衡字符串
在一个「平衡字符串」中,'L' 和 'R' 字符的数量是相同的. 给出一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串. 返回可以通过分割得到的平衡字符串的最大数量. 示例 1: 输入:s = ...
- nginx 80端口强制转443
server { listen 80; server_name test.com; rewrite ^(.*)$ https://${server_name}$1 permanent; } serve ...
- ASP.NET Core 6框架揭秘实例演示[11]:诊断跟踪的几种基本编程方式
在整个软件开发维护生命周期内,最难的不是如何将软件系统开发出来,而是在系统上线之后及时解决遇到的问题.一个好的程序员能够在系统出现问题之后马上定位错误的根源并找到正确的解决方案,一个更好的程序员能够根 ...
- CobaltStrike逆向学习系列(10):TeamServer 启动流程分析
这是[信安成长计划]的第 10 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 基本校验与解析 0x02 初始化 0x03 启动 Listeners 在之前的分析中,都是针对 Cob ...
- [题解]Codeforces Round #519 - B. Lost Array
[题目] B. Lost Array [描述] Bajtek有一个数组x[0],x[1],...,x[k-1]但被搞丢了,但他知道另一个n+1长的数组a,有a[0]=0,对i=1,2,...,n.由此 ...