http://uoj.ac/problem/112

先扣掉在同一侧的情况。

当\(k=1\)时,桥建在所有位置的中位数。

当\(k=2\)时,对于每个居民\((S_i,T_i)\),这个居民只会走离\(\frac{S_i+T_i}2\)最近的桥,那么对所有\(\frac{S_i+T_i}2\)排序,最优方案一定满足排序后的居民从中间分开,左边的居民走左边的桥,右边的居民走右边的桥。

从左往右扫,不断加入“左边的居民”,“左边的桥”建在当前“左边的居民”的所有\(S_i\)和\(T_i\)的中位数上,动态维护这个中位数就可以了。右边同理,最后合并答案即可。

对于动态维护中位数,考虑到每次加两个数,中位数只会在相邻的位置间左右横跳,所以维护前驱和后继就可以了。这里可以用树状数组/权值线段树维护前驱后继(前缀最大值,后缀最小值)。

时间复杂度\(O(n\log n)\)。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll; const int N = 100003; struct node {
int x, y;
bool operator < (const node &A) const {
return x + y < A.x + A.y;
}
} Q[N]; ll ans = 0;
int H[N << 1], cnt = 0, n, k, Si, Ti, tot = 0;
char pi, qi; namespace hahaha {
void solve() {
cnt = 0;
for (int i = 1; i <= tot; ++i)
H[++cnt] = Q[i].x, H[++cnt] = Q[i].y;
stable_sort(H + 1, H + cnt + 1); ll sum, ret = 0;
for (int i = cnt >> 1; i >= 1; --i) ret += H[i];
sum = ret;
for (int i = (cnt >> 1) + 1; i <= cnt; ++i) sum += H[i]; ans += sum - (ret << 1);
printf("%lld\n", ans);
}
} template <typename T> void check_max(T &a, T b) {if (b > a) a = b;}
template <typename T> void check_min(T &a, T b) {if (b < a) a = b;} namespace miaomiaomiao {
ll f1[N], f2[N];
int bitsl[N << 1], bitsr[N << 1], id[N << 1]; bool cmp(int x, int y) {return (x > tot ? Q[x - tot].y : Q[x].x) < (y > tot ? Q[y - tot].y : Q[y].x);} void insl(int x) {
for (int t = x; t <= cnt; t += t & -t)
check_max(bitsl[t], x);
} void insr(int x) {
for (int t = x; t; t -= t & -t)
check_min(bitsr[t], x);
} int findl(int x) {
int ret = 0;
for (int t = x - 1; t; t -= t & -t)
check_max(ret, bitsl[t]);
return ret;
} int findr(int x) {
int ret = cnt + 1;
for (int t = x + 1; t <= cnt; t += t & -t)
check_min(ret, bitsr[t]);
return ret;
} void work(ll *f) {
int mid = 0; ll ret = 0, sum = 0;
for (int i = 1; i <= cnt; ++i) bitsl[i] = 0, bitsr[i] = cnt + 1;
for (int i = 1; i <= tot; ++i) {
int x = Q[i].x, y = Q[i].y;
insl(x); insl(y);
insr(x); insr(y);
sum += H[x]; sum += H[y];
if (x < mid && y > mid || y < mid && x > mid)
ret += H[min(x, y)];
else if (x < mid) {
ret -= H[mid];
ret += H[x]; ret += H[y];
mid = findl(mid);
} else {
mid = findr(mid);
ret += H[mid];
}
f[i] = sum - (ret << 1);
}
} void solve() {
for (int i = 1; i <= (tot << 1); ++i) id[i] = i;
stable_sort(Q + 1, Q + tot + 1);
stable_sort(id + 1, id + (tot << 1) + 1, cmp);
cnt = 0;
for (int i = 1; i <= (tot << 1); ++i) {
++cnt;
if (id[i] > tot) H[cnt] = Q[id[i] - tot].y, Q[id[i] - tot].y = cnt;
else H[cnt] = Q[id[i]].x, Q[id[i]].x = cnt;
} work(f1);
reverse(Q + 1, Q + tot + 1);
work(f2); ll ra = f2[tot];
for (int i = 1; i <= tot; ++i)
check_min(ra, f1[i] + f2[tot - i]);
printf("%lld\n", ans + ra);
}
} int main() {
scanf("%d%d", &k, &n);
for (int i = 1; i <= n; ++i) {
for (pi = getchar(); pi != 'A' && pi != 'B'; pi = getchar());
scanf("%d", &Si);
for (qi = getchar(); qi != 'A' && qi != 'B'; qi = getchar());
scanf("%d", &Ti);
if (qi == pi) ans += abs(Ti - Si);
else {
Q[++tot] = (node) {Si, Ti};
++ans;
}
} if (k == 1) hahaha::solve();
else miaomiaomiao::solve(); return 0;
}

【UOJ #112】【APIO 2015】Palembang Bridges的更多相关文章

  1. 【CTSC 2015】&【APIO 2015】酱油记

    蒟蒻有幸参加了神犇云集的CTSC & APIO 2015,感觉真是被虐成傻逼了……这几天一直没更新博客,今天就来补一下吧~~(不过不是题解……) Day 0 从太原到北京现在坐高铁只需3小时= ...

  2. 【UOJ #110】【APIO 2015】Bali Sculptures

    http://uoj.ac/problem/110 这道题subtask4和subtask5是不同的算法. 主要思想都是从高位到低位贪心确定答案. 对于subtask4,n比较小,设\(f(i,j)\ ...

  3. 【BZOJ 4070】【APIO 2015】雅加达的摩天楼

    http://www.lydsy.com/JudgeOnline/problem.php?id=4070 分块建图. 对每个\(P_i\)分类讨论,\(P_i>\sqrt N\)则直接连边,边数 ...

  4. 【MyEclipse 2015】 逆向破解实录系列【终】(纯研究)

    声明 My Eclipse 2015 程序版权为Genuitec, L.L.C所有. My Eclipse 2015 的注册码.激活码等授权为Genuitec, L.L.C及其付费用户所有. 本文只从 ...

  5. 【MyEclipse 2015】 逆向破解实录系列【2】(纯研究)

    声明 My Eclipse 2015 程序版权为Genuitec, L.L.C所有. My Eclipse 2015 的注册码.激活码等授权为Genuitec, L.L.C及其付费用户所有. 本文只从 ...

  6. 【CEDEC 2015】【夏日课堂】制作事宜技术篇,新手职员挑战VR Demo开发的真相

    日文原文地址 http://www.4gamer.net/games/277/G027751/20150829002/ PS:CEDEC 2015的PPT有些要到10月才有下载,目前的都是记者照片修图 ...

  7. 【SIGGRAPH 2015】【巫师3 狂猎 The Witcher 3: Wild Hunt 】顶级的开放世界游戏的实现技术。

    [SIGGRAPH 2015][巫师3 狂猎 The Witcher 3: Wild Hunt ]顶级的开放世界游戏的实现技术 作者:西川善司 日文链接  http://www.4gamer.net/ ...

  8. 【UOJ】67 新年的毒瘤 &【BZOJ】1123 BLO

    [UOJ 67] 题目链接: 传送门 题解: 第一眼很懵逼……这什么鬼. 思考什么点复合条件……(o(>﹏<)o 1.树,也就是说还剩n-2条边,等价于要删去一个度数为m-n+2的点. 2 ...

  9. 【UOJ#236】[IOI2016]railroad(欧拉回路,最小生成树)

    [UOJ#236][IOI2016]railroad(欧拉回路,最小生成树) 题面 UOJ 题解 把速度看成点,给定的路段看成边,那么现在就有了若干边,然后现在要补上若干边,以及一条\([inf,\) ...

随机推荐

  1. oschina ios开发学习

    应该跟android版的类似,例如服务器端在oschina-prefix.pch里 #define api_news_list @"http://www.oschina.net/action ...

  2. laravel中form表单,ajax传值没反应

    laravel中form表单,ajax传值没反应时,可能是令牌有问题. form中添加: {{csrf_token()}} ajax中添加: data: {'page': page, '_token' ...

  3. void指针和NULL指针

    Void指针和NULL指针 Void指针: Void指针我们称之为通用指针,就是可以指向任意类型的数据.也就是说,任何类型的指针都可以赋值给Void指针. 举例: #include<stdio. ...

  4. Price(洛谷P4109 [HEOI2015]定价)

    题目 思路: 按照我的思路这一题应该是这样子的 剔除+判断 剔除 因为后面的0要越多越好,所以我们判断0出现的情况,当2个数之间的差大与10时,证明2个之间会存在一个0,所以这一位我们可以把它去掉,相 ...

  5. Redis笔记之常用命令

    keys keys用来获取符合指定规则的键,keys的语法规则如下: keys <pattern> 比如最简单的全等匹配,下面这个命令只会匹配键值完全等于foo的: 127.0.0.1:6 ...

  6. 49、是否使用过functools中的函数?其作用是什么?

    functools模块介绍 functools用于高阶函数:指那些作用于函数或者返回其他函数的函数.通常情况下,只要是可以被当做函数调用的对象就是这个模块的目标. functools模块的功能 pyt ...

  7. python并发编程之threading线程(一)

    进程是系统进行资源分配最小单元,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.进程在执行过程中拥有独立的内存单元,而多个线程共享内存等资源. 系列文章 py ...

  8. git 还原到指定版本号

      git clone git branch -r --contains 88b92060224e96ef209565fa75c816eb9b0fae8e git checkout origin/re ...

  9. android 动态改变控件位置和大小 .

    动态改变控件位置的方法: setPadding()的方法更改布局位置. 如我要把Imageview下移200px:             ImageView.setPadding( ImageVie ...

  10. IO的学习与使用

    一.IO的学习方法:IO中包含了很多的类,推荐的学习方式是:“举一反三,掌握一种,以此类推”. 二.I/O操作的目标: 输入:从数据源(在数据源和程序之间建立的一个数据流淌的“管道”)中读取数据(文件 ...