【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\)的情况了

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

所以要找个东西来维护

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

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define MAX 250000
#define lson (now<<1)
#define rson (now<<1|1)
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Node{int a,b;}w[MAX];
bool operator<(Node a,Node b){return a.a+a.b<b.a+b.b;}
int cnt;
long long ans;
int K,n,a[MAX],b[MAX],S[MAX],top;
struct SegMentTree
{
struct node
{
int size;ll sum;
}t[MAX<<2];
int Kth(int now,int l,int r,int k)
{
if(l==r)return l;
int mid=(l+r)>>1;
if(k<=t[lson].size)return Kth(lson,l,mid,k);
else return Kth(rson,mid+1,r,k-t[lson].size);
}
void Modify(int now,int l,int r,int pos,int ww)
{
t[now].size+=ww;t[now].sum+=1ll*ww*S[pos];
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid)Modify(lson,l,mid,pos,ww);
else Modify(rson,mid+1,r,pos,ww);
}
ll QueryV(int now,int l,int r,int al,int ar)
{
if(al<=l&&r<=ar)return t[now].sum;
int mid=(l+r)>>1;ll ret=0;
if(al<=mid)ret+=QueryV(lson,l,mid,al,ar);
if(ar>mid)ret+=QueryV(rson,mid+1,r,al,ar);
return ret;
}
int QueryS(int now,int l,int r,int al,int ar)
{
if(al<=l&&r<=ar)return t[now].size;
int mid=(l+r)>>1,ret=0;
if(al<=mid)ret+=QueryS(lson,l,mid,al,ar);
if(ar>mid)ret+=QueryS(rson,mid+1,r,al,ar);
return ret;
}
}T[2];
int main()
{
K=read();n=read();
char ch[2];
if(K==1)
{
int tot=0;
for(int i=1;i<=n;++i)
{
scanf("%s",ch);int p=ch[0]-'A';
int s=read();
scanf("%s",ch);int q=ch[0]-'A';
int t=read();
if(p==q){ans+=abs(s-t);continue;}
else if(p==1)swap(s,t);
++tot;a[tot]=s;b[tot]=t;S[++top]=s;S[++top]=t;
}
sort(&S[1],&S[top+1]);
int G=S[top/2];
for(int i=1;i<=top;++i)ans+=abs(G-S[i]);
printf("%lld\n",ans+tot);
return 0;
}
for(int i=1;i<=n;++i)
{
scanf("%s",ch);int p=ch[0]-'A';
int s=read();
scanf("%s",ch);int q=ch[0]-'A';
int t=read();
if(p==q){ans+=abs(s-t);continue;}
ans++;S[++top]=s;S[++top]=t;
if(s>t)swap(s,t);
w[++cnt]=(Node){s,t};
}
if(!cnt){printf("%lld\n",ans);return 0;}
sort(&w[1],&w[cnt+1]);
sort(&S[1],&S[top+1]);
top=unique(&S[1],&S[top+1])-S-1;
for(int i=1;i<=cnt;++i)
{
w[i].a=lower_bound(&S[1],&S[top+1],w[i].a)-S;
w[i].b=lower_bound(&S[1],&S[top+1],w[i].b)-S;
T[1].Modify(1,1,top,w[i].a,1);
T[1].Modify(1,1,top,w[i].b,1);
}
long long sum=1e18;
for(int i=1;i<=cnt;++i)
{
T[0].Modify(1,1,top,w[i].a,1);
T[0].Modify(1,1,top,w[i].b,1);
T[1].Modify(1,1,top,w[i].a,-1);
T[1].Modify(1,1,top,w[i].b,-1);
int p1=T[0].Kth(1,1,top,i);//找中位数
int p2=T[1].Kth(1,1,top,cnt-i);
long long D0=0;
D0+=1ll*T[0].QueryS(1,1,top,1,p1)*S[p1]-T[0].QueryV(1,1,top,1,p1);
D0+=T[0].QueryV(1,1,top,p1,top)-1ll*T[0].QueryS(1,1,top,p1,top)*S[p1];
long long D1=0;
D1+=1ll*T[1].QueryS(1,1,top,1,p2)*S[p2]-T[1].QueryV(1,1,top,1,p2);
D1+=T[1].QueryV(1,1,top,p2,top)-1ll*T[1].QueryS(1,1,top,p2,top)*S[p2];
sum=min(sum,D0+D1);
}
printf("%lld\n",ans+sum);
return 0;
}

【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. LeetCode - 596. Classes More Than 5 Students

    There is a table courses with columns: student and class Please list out all classes which have more ...

  2. android应用中去android市场去评分的功能实现(吐槽一波个人应用上线...)

    一般的app可能会有这中功能,在应用中去android商店评分来提高排名,前段时间也把我的博客园上传到商店,这里不得不吐槽一些android商店的开放平台. 酷派,vivo,oppo,联想不支持个人开 ...

  3. [JSOI2008]最大数maxnumber

    [JSOI2008]最大数maxnumber 标签: 线段树 单独队列 题目链接 题解 线段树裸题. 如果一直RE可能是你用的cin/cout. Code #include<cstdio> ...

  4. JAVA死锁

    死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不能正常运行. 简单的说就是:线程死锁时,第一个线程等待第二个线程释放资源,而同时第 ...

  5. .NET常用第三方库(包)总结

    文章会不定期更新,以下内容均为个人总结,欢迎各位拍砖指正 序列化与反序列化 JSON.NET应该是.NET平台上使用最为广泛的序列化/反序列化包了,ASP.NET和ASP.NET Core中默认序列化 ...

  6. 浅谈PHP答题卡识别(一)

    最近期末考试考完了,我们也要放寒假了.于是突发奇想,想用PHP写一个答题卡识别程序.已经实现了一些,现分享给大家. 具体的步骤如下: 上传答题卡=>图片二值化(已实现)=>寻找定位点(已实 ...

  7. Selenium常用API用法示例集----下拉框、文本域及富文本框、弹窗、JS、frame、文件上传和下载

    元素识别方法.一组元素定位.鼠标操作.多窗口处理.下拉框.文本域及富文本框.弹窗.JS.frame.文件上传和下载 元素识别方法: driver.find_element_by_id() driver ...

  8. Oracle中的多表查询(笛卡尔积原理)

    本次预计讲解的知识点 1. 多表查询的操作.限制.笛卡尔积的问题: 2. 统计函数及分组统计的操作: 3. 子查询的操作,并且结合限定查询.数据排序.多表查询.统计查询一起完成各个复杂查询的操作: 一 ...

  9. java-redis列表数据操作示例(二)

    接上篇博文<java-redis字符类数据操作示例(一)>,redis连接管理类的代码请跳转查看. 一.列表类型缓存测试类 public class ListTest { /** * 主测 ...

  10. uva10603 倒水问题

    状态搜索.类似八数码问题 AC代码 #include<cstdio> #include<queue> #include<cstring> #include<a ...