【BZOJ4071】【APIO2015】巴邻旁之桥
题意:
Description
一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B。
子任务 1 (8 分)K=1,1≤N≤1000
子任务 2 (14 分)K=1,1≤N≤100000
子任务 3 (9 分)K=2,1≤N≤100
子任务 4 (32 分)K=2,1≤N≤1000
子任务 5 (37 分)K=2,1≤N≤100000
Input
输入的第一行包含两个正整数 K 和 N,分别表示桥的上限数量和居民的数量。
Output
题解:
首先,这题可以三分!可以三分!可以三分!
认(sui)真(bian)分(cai)析(xiang)一下可以发现,$K=1$时总花费时间随桥从左到右变化的函数是个单峰函数,$K=2$时是两个单峰函数通过某种变换之后叠加在一起,最后还是个单峰函数(然而我并不会证)
因此可以先三分第一个桥,再三分第二个桥,三分套三分的时间复杂度是$O(nlog^210^9)$的,手算大概有2.5亿,实测可以过掉前四个subtask,获得63分的好成绩(雾)
正解是权值线段树动态维护中位数。。。
$K=1$就不说了,大家都会。。。
$K=2$时有一个结论:每个人必定会走更接近$\frac{A_i+B_i}{2}$的那座桥,易得这样必定更优;
所以可以先按照$A_i+B_i$排序,左半边的人就会走左桥,右半边就走右桥;
然后就没了。。。左右各写一个数据结构,支持快速插入/删除,快速查询中位数和区间和,可以直接splay,也可以用权值线段树黑科技来做(新技能get√)
ps:所谓的黑科技就是,左右儿子哪个size大就走哪个,最后的叶节点就是中位数。。。
代码:
三分:(请木公爷来卡常啊啊啊)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 10000000000000000
#define eps 1e-9
using namespace std;
typedef long long ll;
struct pp{
ll s1,s2,t1,t2;
}p[];
ll n,K,ans=inf,l,r,maxn=;
char sd1[],sd2[];
ll gaogao(ll k,ll kk){
ll ret=;
for(ll i=;i<=n;i++){
if(p[i].s1==p[i].s2)ret+=abs(p[i].t1-p[i].t2);
else ret+=min(abs(p[i].t1-k)+abs(p[i].t2-k)+,abs(p[i].t1-kk)+abs(p[i].t2-kk)+);
}
return ret;
}
ll gao(ll k){
if(K==){
ll ret=;
for(ll i=;i<=n;i++){
if(p[i].s1==p[i].s2)ret+=abs(p[i].t1-p[i].t2);
else ret+=abs(p[i].t1-k)+abs(p[i].t2-k)+;
}
return ret;
}
ll ret=inf,l=,r=maxn;
while(l+<=r){
ll mid=l+(r-l)/,mmid=r-(r-l)/;
if(gaogao(k,mid)<=gaogao(k,mmid))r=mmid;
else l=mid;
}
for(ll i=l;i<=r;i++){
ret=min(ret,gaogao(k,i));
}
return ret;
}
int main(){
scanf("%lld%lld",&K,&n);
for(ll i=;i<=n;i++){
scanf("%s%lld%s%lld",sd1,&p[i].t1,sd2,&p[i].t2);
p[i].s1=sd1[]-'A';
p[i].s2=sd2[]-'A';
maxn=max(maxn,max(p[i].t1,p[i].t2));
}
l=,r=maxn;
while(l+<=r){
ll mid=l+(r-l)/,mmid=r-(r-l)/;
if(gao(mid)<=gao(mmid))r=mmid;
else l=mid;
}
for(ll i=l;i<=r;i++){
ans=min(ans,gao(i));
}
printf("%lld",ans);
return ;
}
权值线段树:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 1000000000000000
#define eps 1e-9
using namespace std;
typedef long long ll;
struct pp{
ll t1,t2;
friend bool operator <(pp a,pp b){
return a.t1+a.t2<b.t1+b.t2;
}
}p[];
struct node{
ll v,siz;
}t[][];
ll n,k,t1,t2,x1,x2,x3,x4,m1,m2,nw1=,nw2=,els=,sum=,cnt=,ans=inf,num[];
char s1[],s2[];
void updata(ll l,ll r,ll u,ll p,ll x,ll ch){
t[u][ch].siz+=x;
t[u][ch].v+=x*num[p];
if(l==r)return;
ll mid=(l+r)/;
if(p<=mid)updata(l,mid,u*,p,x,ch);
else updata(mid+,r,u*+,p,x,ch);
}
ll get(ll l,ll r,ll u,ll x,ll ch){
if(l==r)return l;
ll mid=(l+r)/;
if(x<=t[u*][ch].siz)return get(l,mid,u*,x,ch);
else return get(mid+,r,u*+,x-t[u*][ch].siz,ch);
}
ll query(ll l,ll r,ll u,ll L,ll R,ll ch,ll xx){
if(L<=l&&r<=R){
return xx?t[u][ch].v:t[u][ch].siz;
}
ll mid=(l+r)/,ret=;
if(L<=mid)ret+=query(l,mid,u*,L,R,ch,xx);
if(mid<R)ret+=query(mid+,r,u*+,L,R,ch,xx);
return ret;
}
int main(){
scanf("%lld%lld",&k,&n);
if(k==){
for(ll i=;i<=n;i++){
scanf("%s%lld%s%lld",s1,&t1,s2,&t2);
if(s1[]==s2[])els+=abs(t1-t2);
else{
num[++cnt]=t1;
num[++cnt]=t2;
}
}
ans=els+cnt/;
sort(num+,num+cnt+);
for(ll i=;i<=cnt;i++){
ans+=abs(num[i]-num[cnt/]);
}
printf("%lld",ans);
}else{
for(ll i=;i<=n;i++){
scanf("%s%lld%s%lld",s1,&t1,s2,&t2);
if(s1[]==s2[])els+=abs(t1-t2);
else{
num[++cnt]=t1;
num[++cnt]=t2;
p[++sum].t1=t1;
p[sum].t2=t2;
}
}
if(!sum)return printf("%lld\n",els),;
els+=sum;
sort(num+,num+cnt+);
cnt=unique(num+,num+cnt+)-num-;
sort(p+,p+sum+);
for(ll i=;i<=sum;i++){
nw1+=p[i].t1+p[i].t2;
p[i].t1=lower_bound(num+,num+cnt+,p[i].t1)-num;
p[i].t2=lower_bound(num+,num+cnt+,p[i].t2)-num;
updata(,cnt,,p[i].t1,,);
updata(,cnt,,p[i].t2,,);
}
for(ll i=;i<=sum;i++){
nw2+=num[p[i].t1]+num[p[i].t2];
nw1-=num[p[i].t1]+num[p[i].t2];
updata(,cnt,,p[i].t1,,);
updata(,cnt,,p[i].t1,-,);
updata(,cnt,,p[i].t2,,);
updata(,cnt,,p[i].t2,-,);
m1=get(,cnt,,i,);
m2=get(,cnt,,sum-i,);
x1=query(,cnt,,,m1,,);
x2=query(,cnt,,,m2,,);
x3=query(,cnt,,,m1,,);
x4=query(,cnt,,,m2,,);
ans=min(ans,x3*num[m1]-x1+(nw2-x1)-(i*-x3)*num[m1]+x4*num[m2]-x2+(nw1-x2)-((sum-i)*-x4)*num[m2]);
}
printf("%lld",ans+els);
}
return ;
}
【BZOJ4071】【APIO2015】巴邻旁之桥的更多相关文章
- [bzoj4071] [Apio2015]巴邻旁之桥
Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 10000 ...
- 【BZOJ4071】[Apio2015]巴邻旁之桥 Treap
[BZOJ4071][Apio2015]巴邻旁之桥 Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 ...
- BZOJ4071 & 洛谷3644 & UOJ112:[APIO2015]巴邻旁之桥——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4071 https://www.luogu.org/problemnew/show/P3644 ht ...
- 4071: [Apio2015]巴邻旁之桥
Description 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域 A 和区域 B. 每一块区域沿着河岸都建了恰好 1000000001 栋的建筑,每条岸边的建筑都从 0 编号到 10000 ...
- [BZOJ4071][APIO2015]八邻旁之桥
BZOJ(这题是BZOJ权限题,有权限号的就去看看吧) Luogu(良心洛谷) 题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域\(A\)和区域\(B\). 每一块区域沿着河岸都建了恰好 ...
- [APIO2015]巴邻旁之桥
Bzoj权限题 luogu题面 先去掉同边的 首先k==1,即求一个点j 使\(\sum_{i\in A} |D_i - D_j| + \sum_{i\in B} |D_i - D_j|\)最小 因为 ...
- bzoj 4071: [Apio2015]巴邻旁之桥【splay】
用权值线段树会容易一些并快一些,但是想复健一下splay所以打了splay 然后果然不会打了. 解题思路: 首先把家和办公室在同一侧的提出来直接加进答案里: 对于k=1,直接选所有办公室和家的中位数即 ...
- 洛谷 P3644 [APIO2015]八邻旁之桥 解题报告
P3644 [APIO2015]八邻旁之桥 题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域\(A\)和区域\(B\). 每一块区域沿着河岸都建了恰好\(1000000001\)栋的建筑 ...
- 【BZOJ4071】八邻旁之桥(线段树)
[BZOJ4071]八邻旁之桥(线段树) 题面 BZOJ权限题,洛谷链接 题解 既然\(k<=2\) 那么,突破口就在这里 分类讨论 ①\(k=1\) 这...不就是中位数吗.... 直接把所有 ...
- [APIO2015]八邻旁之桥——非旋转treap
题目链接: [APIO2015]八邻旁之桥 对于$k=1$的情况: 对于起点和终点在同侧的直接计入答案:对于不在同侧的,可以发现答案就是所有点坐标与桥坐标的差之和+起点与终点不在同一侧的人数. 将所有 ...
随机推荐
- Django框架详解之template
模板简介 将页面的设计和python的代码分离开会更干净简洁更容易维护.我们可以使用Django的模板系统来实现这种模式 python的模板:HTML代码+模板语法 模板包括在使用时会被值替换掉的变量 ...
- Python 进行网络编程
Date: 2019-06-10 Author: Sun 1. Python TCP通信实现 socket()函数 Python 中,我们用 socket()函数来创建套接字,语法格式如下: sock ...
- pytorch实战(2)-----回归例子
一.回归任务介绍: 拟合一个二元函数 y = x ^ 2. 二.步骤: 导入包 创建数据 构建网络 设置优化器和损失函数 前向和后向传播训练网络 画图 三.代码: 导入包: import torch ...
- 用于构建 RESTful Web 服务的多层架构
作者:Bruce Sun, Java 架构师, IBM 出处:http://www.ibm.com/developerworks/cn/web/wa-aj-multitier/ 用于构建 RESTfu ...
- 定位前后端bug
说明 1 : js是静态资源,会缓存到浏览器的客户端,为了清除缓存,需要强制刷新页面,所有的东西强制的到服务器上拿一下 说明 2 :http状态码,服务器响应的一个状态码,标记不同的处理结果 说明 ...
- 51nod 1302(贪心+平衡树)
能推出一些性质. 矩形肯定是全部躺着或全部立着比较优. 如图x1显然等于x2,y1显然小于y2. 所以我们就让它们都躺下吧. 然后一定有一组的宽为宽最小的矩形的宽. 然后我们枚举另一组的宽最小的矩形. ...
- BZOJ 2329/2209 [HNOI2011]括号修复 (splay)
题目大意: 让你维护一个括号序列,支持 1.区间修改为同一种括号 2.区间内所有括号都反转 3.翻转整个区间,括号的方向不变 4.查询把某段区间变为合法的括号序列,至少需要修改多少次括号 给跪了,足足 ...
- CF482C Game with Strings (状压DP+期望DP)
题目大意:甲和乙玩游戏,甲给出n(n<=50)个等长的字符串(len<=20),然后甲选出其中一个字符串,乙随机询问该字符串某一位的字符(不会重复询问一个位置),求乙能确定该串是哪个字符串 ...
- JQuery封装ajax的方法
1.$.post方法 $.post(url[,data][,callback][,type]) url:请求的后台程序地址 data:发送到后台的数据 callback:载入成功时回调函数,该函数参数 ...
- Linux配置nignx虚拟主机
Nginx 是一个轻量级高性能的 Web 服务器, 并发处理能力强, 对资源消耗小, 无论是静态服务器还是小网站, Nginx 表现更加出色, 作为 Apache 的补充和替代使用率越来越高. 我在& ...