题目描述:

bz

luogu

题解:

贪心+权值线段树。

$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 八邻旁之桥/巴邻旁之桥的更多相关文章

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

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

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

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

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

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

  4. 4071: [Apio2015]巴邻旁之桥

    Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 10000 ...

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

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

  6. BZOJ4071 & 洛谷3644 & UOJ112:[APIO2015]巴邻旁之桥——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4071 https://www.luogu.org/problemnew/show/P3644 ht ...

  7. [bzoj4071] [Apio2015]巴邻旁之桥

    Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 10000 ...

  8. 【BZOJ4071】【APIO2015】巴邻旁之桥

    题意: Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 1 ...

  9. Appium+python自动化(二十八)- 滑呀滑,滑到奈何桥喝碗孟婆汤 - 高级滑动(超详解)

    简介 奈何桥上叹奈何,三生石前憾三生,彼岸花下非彼岸,奈何三生彼岸人. 相传过了鬼门关便上一条路叫黄泉路,路上盛开着只见花,不见叶的彼岸花.花叶生生两不见,相念相惜永相失,路尽头有一条河叫忘川河,河上 ...

随机推荐

  1. 【JOISC 2020 补题记录】

    目录 Day 1 Building 4 Hamburg Steak Sweeping Day 2 Chameleon's Love Making Friends on Joitter is Fun R ...

  2. C#使用 WebRequest 异步获取网页并自动忽略SSL证书

    C#使用 WebRequest 模拟浏览器请求访问网页并自动忽略HTTPS安全证书 以下两个C#异步方法,封装了WebRequest请求,支持忽略SSL证书. 作者:张赐荣 1.Get请求      ...

  3. operator 之旅(一)

    环境准备 依赖版本 MAC M1 kubernetes: 1.18.3 go: 1.17.6 kubebuilder:3.1.0 知识必备 Kubernetes的Group.Version.Resou ...

  4. python控制浏览器上传文件

    自动化爬虫方法和库很多,难点大多数在登录.可以大致分为:普通验证码,扫码登录,QQ一键登录,拖动验证,无痕验证,人工识别(比如12306登录) 万能大法可以破解一切以上需求,自动控制浏览器行为 参考文 ...

  5. 图解AI数学基础 | 线性代数与矩阵论

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/83 本文地址:http://www.showmeai.tech/article-det ...

  6. 图的深度遍历(C语言)邻接矩阵表示

    知识讲解: 图的遍历分为两种,深度遍历与广度遍历.这里讨论深度遍历. 以上图为例讨论图(图片来自<算法笔记>)的深度遍历: 设图形的顶点数为n. 先从顶点v0开始,用一个数组vis[n]来 ...

  7. 八大排序算法之直接插入排序(InsertionSort)

    常见的排序算法 今天复习[直接插入排序] 核心思想:有序数组中 找位置 -- 给无序数组第一个 找位置 ` public class InsertionSort { // 核心思想:有序数组中 找位置 ...

  8. Spring源码之BeanFactoryPostProcessor(后置处理器)

    Spring源码之BeanFactoryPostProcessor(后置处理器). 有点水平的Spring开发人员想必都知道BeanFactoryPostProcessor也就是常说的后置管理器,这是 ...

  9. Win10系统下WampServer运行之后显示橙色如何变成绿色的方法

    我们可能会安装wampserver在本地环境下测试网站,不过wampserver运行之后,wampserver的图标呈现出橙色,而不是绿色,这就说明了wampserver在本地环境没有启动成功.那么我 ...

  10. python基础之数值类型与序列类型

    Hello大家好,我是python学习者小杨同学,已经学习python有一段时间,今天将之前学习过的内容整理一番,在这与大家分享与交流,现在开始我们的python基础知识之旅吧. 数值类型与序列类型 ...