巴邻旁之桥
2015-06-10 18:48
295 查看
Description
一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B。
每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 1000000000。相邻的每对建筑相隔 1 个单位距离,河的宽度也是 1 个单位长度。区域 A 中的 i 号建筑物恰好与区域 B 中的 i 号建筑物隔河相对。
城市中有 N 个居民。第 i 个居民的房子在区域 Pi 的 Si 号建筑上,同时他的办公室坐落在 Qi 区域的 Ti 号建筑上。一个居民的房子和办公室可能分布在河的两岸,这样他就必须要搭乘船只才能从家中去往办公室,这种情况让很多人都觉得不方便。为了使居民们可以开车去工作,政府决定建造不超过 K 座横跨河流的大桥。
由于技术上的原因,每一座桥必须刚好连接河的两岸,桥梁必须严格垂直于河流,并且桥与桥之间不能相交。当政府建造最多 K 座桥之后,设 Di 表示第 i 个居民此时开车从家里到办公室的最短距离。请帮助政府建造桥梁,使得 D1+D2+?+DN 最小。
Input
输入的第一行包含两个正整数 K 和 N,分别表示桥的上限数量和居民的数量。
接下来 N 行,每一行包含四个参数:Pi,Si,Qi 和 Ti,表示第 i 个居民的房子在区域 Pi 的 Si 号建筑上,且他的办公室位于 Qi 区域的 Ti 号建筑上。
Output
输出仅为一行,包含一个整数,表示 D1+D2+?+DN 的最小值。
Sample Input
1 5
B 0 A 4
B 1 B 3
A 5 B 7
B 2 A 6
B 1 A 7
Sample Output
24
HINT
K=1或K=2
1≤N≤100000
题解
(家和单位在同一侧的提前算好)
当把所求的计算式列出之后,可以发现最优解是所有办公室和家的位置的中位数。
对于k=1的,中位数可以直接求出。
对于k=2的,可以发现:按照每个人的家和办公室的中点排序后,一定存在一个分割点使得前缀都走左边的桥,后缀都走右边的桥(因为走靠近中点的桥不会更差)。
于是我们枚举分割点,离散化后用权值线段树动态维护两个区间的中位数求解即可。
一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B。
每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 1000000000。相邻的每对建筑相隔 1 个单位距离,河的宽度也是 1 个单位长度。区域 A 中的 i 号建筑物恰好与区域 B 中的 i 号建筑物隔河相对。
城市中有 N 个居民。第 i 个居民的房子在区域 Pi 的 Si 号建筑上,同时他的办公室坐落在 Qi 区域的 Ti 号建筑上。一个居民的房子和办公室可能分布在河的两岸,这样他就必须要搭乘船只才能从家中去往办公室,这种情况让很多人都觉得不方便。为了使居民们可以开车去工作,政府决定建造不超过 K 座横跨河流的大桥。
由于技术上的原因,每一座桥必须刚好连接河的两岸,桥梁必须严格垂直于河流,并且桥与桥之间不能相交。当政府建造最多 K 座桥之后,设 Di 表示第 i 个居民此时开车从家里到办公室的最短距离。请帮助政府建造桥梁,使得 D1+D2+?+DN 最小。
Input
输入的第一行包含两个正整数 K 和 N,分别表示桥的上限数量和居民的数量。
接下来 N 行,每一行包含四个参数:Pi,Si,Qi 和 Ti,表示第 i 个居民的房子在区域 Pi 的 Si 号建筑上,且他的办公室位于 Qi 区域的 Ti 号建筑上。
Output
输出仅为一行,包含一个整数,表示 D1+D2+?+DN 的最小值。
Sample Input
1 5
B 0 A 4
B 1 B 3
A 5 B 7
B 2 A 6
B 1 A 7
Sample Output
24
HINT
K=1或K=2
1≤N≤100000
题解
(家和单位在同一侧的提前算好)
当把所求的计算式列出之后,可以发现最优解是所有办公室和家的位置的中位数。
对于k=1的,中位数可以直接求出。
对于k=2的,可以发现:按照每个人的家和办公室的中点排序后,一定存在一个分割点使得前缀都走左边的桥,后缀都走右边的桥(因为走靠近中点的桥不会更差)。
于是我们枚举分割点,离散化后用权值线段树动态维护两个区间的中位数求解即可。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <map> #include <vector> #define pb push_back #define M 300005 #define LL long long using namespace std; LL ans[M]; int size,n,k,cnt; int ls[M],d[M]; char s1[10],s2[10]; struct data { int x[3]; }a[M]; struct Segtree { int size; LL sum; }t[M<<2]; int z[10]; void lisan() { sort(ls+1,ls+1+cnt); size=unique(ls+1,ls+1+cnt)-ls-1; } int Hash(int x) { return lower_bound(ls+1,ls+1+size,x)-ls; } bool cmp(data a,data b) { return a.x[1]+a.x[2]<b.x[1]+b.x[2]; } void Update(int x) { t[x].sum=t[x<<1].sum+t[x<<1|1].sum; t[x].size=t[x<<1].size+t[x<<1|1].size; } void Build(int x,int l,int r) { if (l==r) { t[x].sum=t[x].size=0; return; } int m=(l+r)>>1; Build(x<<1,l,m); Build(x<<1|1,m+1,r); Update(x); } void Insert(int x,int l,int r,int k) { if (l==r) { t[x].sum+=d[l]; t[x].size++; return; } int m=(l+r)>>1; if (k<=m) Insert(x<<1,l,m,k); else Insert(x<<1|1,m+1,r,k); Update(x); } LL Getsum(int x,int l,int r,int cnt) { if (t[x].size<=cnt) return t[x].sum; if (l==r) return 1LL*cnt*d[l]; int m=(l+r)>>1; if (t[x<<1].size>=cnt) return Getsum(x<<1,l,m,cnt); else return t[x<<1].sum+Getsum(x<<1|1,m+1,r,cnt-t[x<<1].size); } LL Query(LL k) { LL s=Getsum(1,1,size,k); return t[1].sum-2LL*s; } int main() { scanf("%d%d",&k,&n); LL pre=0; int tot=0; cnt=0; for (int i=1;i<=n;i++) { int x1,x2; scanf("%s%d%s%d",s1,&x1,s2,&x2); if (s1[0]==s2[0]) { pre+=abs(x1-x2); continue; } pre++; a[++tot].x[1]=x1,a[tot].x[2]=x2; ls[++cnt]=x1,ls[++cnt]=x2; } if (cnt) { lisan(); n=tot; for (int i=1;i<=n;i++) d[Hash(a[i].x[1])]=a[i].x[1],d[Hash(a[i].x[2])]=a[i].x[2]; Build(1,1,size); sort(a+1,a+1+n,cmp); for (int i=1;i<=n;i++) { Insert(1,1,size,Hash(a[i].x[1])); Insert(1,1,size,Hash(a[i].x[2])); ans[i]=Query(i); } } if (k==1) cout<<ans +pre<<endl; else { LL Ans=ans ; if (size) { Build(1,1,size); for (int i=n;i>1;i--) { Insert(1,1,size,Hash(a[i].x[1])); Insert(1,1,size,Hash(a[i].x[2])); Ans=min(Ans,ans[i-1]+Query(n-i+1)); } } cout<<Ans+pre<<endl; } return 0; }
相关文章推荐
- 计算机系统笔记
- 使用Microsoft excel 2007 进行数据分析---环境配置
- 探测器 C++ Singleton(辛格尔顿)
- 关于socket长连接的心跳包GOOD
- [leetcode 12] Inter to Roman
- LCA 最裸版
- IOCP本质论
- 导出Excel插件——Export-CSV ---20150610
- 黑马程序员——基础篇——IO(关于hasNextDouble()的使用心得
- 鱼眼拼接之Harris检测特征点
- 毕业课题之------------图像路面直方图建模
- 6.10 UITableView
- How to install libipfix
- 七零后的程序员,人已老,代码亦封存
- Eclipse中jsp、js文件编辑时,卡死现象解决汇总
- 关于<:if>没有<c:else> 可以用<c:choose>来取代结构:
- PHP:编译-执行 分离
- asp.net 使用Oracle数据库
- 黑马程序员_JAVA_基础_1
- leetcode--Binary Tree Inorder Traversal