Codeforces 436E Cardboard Box (看题解)
贪了个半天贪不对, 我发现我根本就不会贪心。
我们先按b排序, 然后枚举选两颗心的b的最大值, 在这个之前的肯定都要选一个, 因为前面的要是一个都没选的话,
你可以把当前选两颗心的替换成前面选两颗心, 然后用平衡树或者线段树维护一下前k大和就好啦。
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 3e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-;
const double PI = acos(-); #define lson l, mid, rt->ls
#define rson mid + 1, r, rt->rs
struct Node {
Node() {
ls = rs = NULL;
sum = cnt = ;
}
Node *ls, *rs;
LL sum;
int cnt;
}; inline void pull(Node* rt) {
rt->cnt = rt->ls->cnt + rt->rs->cnt;
rt->sum = rt->ls->sum + rt->rs->sum;
if(!rt->ls->cnt) delete rt->ls, rt->ls = NULL;
if(!rt->rs->cnt) delete rt->rs, rt->rs = NULL;
}
inline void push(Node* rt) {
if(!rt->ls) rt->ls = new Node();
if(!rt->rs) rt->rs = new Node();
}
void update(int p, int c, int l, int r, Node* rt) {
if(l == r) {
rt->cnt += c;
rt->sum += 1LL * p * c;
return;
}
push(rt);
int mid = l + r >> ;
if(p <= mid) update(p, c, lson);
else update(p, c, rson);
pull(rt);
}
LL query(int k, int l, int r, Node* rt) {
if(!k) return ;
if(rt->cnt <= k) return rt->sum;
if(l == r) return 1LL * k * l;
push(rt);
int mid = l + r >> ;
if(rt->ls->cnt >= k) return query(k, lson);
else return query(rt->ls->cnt, lson) + query(k - rt->ls->cnt, rson);
} int n, w, a[N], b[N], id[N], fin[N];
LL ans = INF; bool cmpa(int x, int y) {
return a[x] < a[y];
}
bool cmpb(int x, int y) {
return b[x] < b[y];
}
int main() {
Node* Rt = new Node();
scanf("%d%d", &n, &w);
for(int i = ; i <= n; i++) scanf("%d%d", &a[i], &b[i]);
for(int i = ; i <= n; i++) id[i] = i;
int where = -;
sort(id + , id + + n, cmpa);
if(w <= n) {
LL ret = ;
for(int i = ; i <= w; i++) ret += a[id[i]];
ans = min(ans, ret);
where = ;
}
sort(id + , id + + n, cmpb);
for(int i = ; i <= n; i++) update(a[id[i]], , , inf, Rt);
LL prefix = ;
LL ret = ;
for(int i = ; i <= n; i++) {
int x = id[i];
update(a[x], -, , inf, Rt);
ret = prefix + b[x];
int need = w - (i + );
if(Rt->cnt >= need) {
ret += query(need, , inf, Rt);
if(ret < ans) {
ans = ret;
where = i;
}
}
prefix += a[x];
update(b[x] - a[x], , , inf, Rt);
}
if(!where) {
sort(id + , id + + n, cmpa);
for(int i = ; i <= w; i++) fin[id[i]] = ;
} else {
priority_queue<PII, vector<PII>, greater<PII> > que;
fin[id[where]] = ;
w -= where + ;
for(int i = ; i < where; i++) que.push(mk(b[id[i]] - a[id[i]], i)), fin[id[i]] = ;
for(int i = where + ; i <= n; i++) que.push(mk(a[id[i]], i));
while(w--) {
int who = que.top().se;
que.pop();
if(who < where) fin[id[who]] = ;
else fin[id[who]] = ;
}
}
printf("%lld\n", ans);
for(int i = ; i <= n; i++) printf("%d", fin[i]);
puts("");
return ;
} /*
*/
Codeforces 436E Cardboard Box (看题解)的更多相关文章
- Codeforces 436E - Cardboard Box(贪心/反悔贪心/数据结构)
题面传送门 题意: 有 \(n\) 个关卡,第 \(i\) 个关卡玩到 \(1\) 颗星需要花 \(a_i\) 的时间,玩到 \(2\) 颗星需要 \(b_i\) 的时间.(\(a_i<b_i\ ...
- Codeforces 269C Flawed Flow (看题解)
我好菜啊啊啊.. 循环以下操作 1.从队列中取出一个顶点, 把哪些没有用过的边全部用当前方向. 2.看有没有点的入度和 == 出度和, 如果有将当前的点加入队列. 现在有一个问题就是, 有没有可能队列 ...
- Codeforces 1045C Hyperspace Highways (看题解) 圆方树
学了一下圆方树, 好神奇的东西呀. #include<bits/stdc++.h> #define LL long long #define fi first #define se sec ...
- Codeforces 1137D Cooperative Game (看题解)
Cooperative Game 智商题, 感觉不太能推出来, 虽然看看证明过程是对的. #include<bits/stdc++.h> #define LL long long #def ...
- Codeforces 875F Royal Questions (看题解)
我还以为是什么板子题呢... 我们把儿子当做点, 公主当做边, 然后就是求边权值最大基环树森林. #include<bits/stdc++.h> #define LL long long ...
- Codeforces 983C Elevator dp (看题解)
Elevator 怎么今天写啥题都不会写啊, 我是傻了吗.. 把电梯里面四个人的目标点当作状态, 然后暴力转移. #include<bits/stdc++.h> #define LL lo ...
- Codeforces 924D Contact ATC (看题解)
Contact ATC 我跑去列方程, 然后就gg了... 我们计每个飞机最早到达时间为L[ i ], 最晚到达时间为R[ i ], 对于面对面飞行的一对飞机, 只要他们的时间有交集则必定满足条件. ...
- Codeforces 830C Bamboo Partition (看题解)
Bamboo Partition 列公式, 整除分块, 想不到, 好菜啊. #include<bits/stdc++.h> #define LL long long #define fi ...
- 题解-CF436E Cardboard Box
题面 CF436E Cardboard Box \(n\) 个关卡,对每个关卡可以花 \(a_i\) 时间得到 \(1\) 颗星,或花 \(b_i\) 时间得到 \(2\) 颗星,或不玩.问获得 \( ...
随机推荐
- $Django Paginator分页器 批量创建数据
1批量插入数据: User_list=[]for i in range(100): User_list.append(User(name='小明%s'%i,pwd='abcdefg%s'%i))# 两 ...
- Centos、Ubuntu开启命令模式
由于安装的虚拟机本来就比较卡,开机加载图形界面,会变的更卡,使用下面的命令可将图形界面关闭. centos: 开机以命令模式启动,执行: systemctl set-default multi-use ...
- sed 用法记录
sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法sed命令行格式为: sed ...
- mgo 的 session 与连接池
简介 mgo是由Golang编写的开源mongodb驱动.由于mongodb官方并没有开发Golang驱动,因此这款驱动被广泛使用.mongodb官网也推荐了这款开源驱动,并且作者在github也表示 ...
- svn:Item ‘XXXXXX’ is out of date
问题描述: 工作副本没有更新到最新版本 svn: 提交失败(细节如下): svn: 目录 "D:\develop\workspace\gxcjx\src\main\resources ...
- [PHP]PDO各方法在发生MYSQL断开时的反应
1.mixed PDO::errorCode ( void ) 如果单独执行此语句,并不能判断此时MYSQL是否已断开,它返回最上一次对MYSQL操作的错误码 2.public array PDO:: ...
- oracle 报表带小计合计
selectcase when (grouping(glbm)=1) then '合计' else DECODE(glbm,null,'',glbm) end glbm,case when (grou ...
- wet 下载jdk 64位
wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com% ...
- 探索一个NSObject对象占用多少内存?
1 下面写代码测试探索NSObject的本质 Objective-C代码,底层实现其实都是C\C++代码 #import <Foundation/Foundation.h> int mai ...
- LeetCode(116):填充同一层的兄弟节点
Medium! 题目描述: 给定一个二叉树 struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *n ...