贪心+离散化+线段树上二分。。。 Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest G. Of Zorcs and Axes
题目链接:http://codeforces.com/gym/101149/problem/G
题目大意:给你n对数字,为(a[i], b[i]),给你m对数字,为(w[i], c[i])。给n对数字找配对,这个配对必须是m中的,而且m中的每个只能和n中的配对一次。
配对条件,w[i]>=a[j], c[i]>=b[j]即可配对。
输出n个数字,每个数字在m个数字当中的配对。
思路:假定n对数字的是x,m对数字的是y
离散化以后sort一下x和y,这样我们就得到了第一维是排序好了的。
然后我们暴力x,每次都把a[i]的值相同的放入线段树,线段树里面储存的是b[i]。
然后如果a[i] != a[i+1],那么我们就暴力y,对于y,暴力其中所有的w[j] < a[i+1]的,然后再线段树中找离c[i]左边最近的那个数字即可。
ORZ,第一次知道queue这么消耗空间,一直MLE了。
//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int inf = 0x3f3f3f3f;
const int maxn = 4e5 + ;
const int maxf = 2e5 + ;
int n, m;
pair<int, pair<int, int> > a[maxf];
pair<int, pair<int, int> > b[maxf];
vector<int> ve;
vector<int> que[maxn * ];
/*
线段树上二分,每次找到和当前的pos最靠近的左端的即可。并且每次保存id
*/
struct Tree{
int cost;
int lft;
}tree[maxn << ];
int ans[maxf]; int update(int pos, int l, int r, int o, int add, int ID = ){
if (pos == l && pos == r){
tree[o].cost += add;
if (add == ) {que[l].push_back(ID); return ;}
if (add == -) {
ID = que[l][tree[o].lft]; tree[o].lft++; return ID;
}
}
int mid = (l + r) / ;
int id = ;
if (pos <= mid) id = update(pos, l, mid, o << , add, ID);
if (pos > mid) id = update(pos, mid + , r, o << | , add, ID);
tree[o].cost = tree[o << ].cost + tree[o << | ].cost;
return id;
} int query(int ql, int qr, int l, int r, int o){
if (l == r){
return l;
}
int mid = (l + r) / ;
int res = ;
if (qr > mid && tree[o << | ].cost > )
res = max(res, query(ql, qr, mid + , r, o << | ));
if (res == && ql <= mid && tree[o << ].cost > )
res = max(res, query(ql, qr, l, mid, o << ));
return res;
} void solve(){
int len = ve.size();
int pos2 = ;
while (b[pos2].fi < a[].fi) pos2++;
a[n + ] = mk(inf, mk(inf, inf));
for(int i = ; i <= n; i++){
update(a[i].se.fi, , len, , , a[i].se.se);
if(a[i].fi != a[i + ].fi) {
while (pos2 <= m && b[pos2].fi < a[i + ].fi){
if (tree[].cost != ){
int x = query(, b[pos2].se.fi, , len, );
if (x){
int id = update(x, , len, , -);
ans[id] = b[pos2].se.se;
}
}
pos2++;
}
}
}
for (int i = ; i <= n; i++){
if (ans[i] == ) {
printf("-1\n"); return;
}
}
for (int i = ; i <= n; i++){
printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
} int main(){
scanf("%d", &n);
for (int i = ; i <= n; i++){
scanf("%d%d", &a[i].fi, &a[i].se.fi);
a[i].se.se = i;
ve.push_back(a[i].fi);
ve.push_back(a[i].se.fi);
}
scanf("%d", &m);
for (int i = ; i <= m; i++){
scanf("%d%d", &b[i].fi, &b[i].se.fi);
b[i].se.se = i;
ve.push_back(b[i].fi);
ve.push_back(b[i].se.fi);
}
if (n > m) {
printf("-1\n"); return ;
}
sort(ALL(ve));
ve.erase(unique(ve.begin(), ve.end()), ve.end());
for (int i = ; i <= n; i++){
a[i].fi = lower_bound(ALL(ve), a[i].fi) - ve.begin() + ;
a[i].se.fi = lower_bound(ALL(ve), a[i].se.fi) - ve.begin() + ;
}
for (int i = ; i <= m; i++){
b[i].fi = lower_bound(ALL(ve), b[i].fi) - ve.begin() + ;
b[i].se.fi = lower_bound(ALL(ve), b[i].se.fi) - ve.begin() + ;
}
sort(a + , a + + n);
sort(b + , b + + m);
solve();
return ;
}
贪心+离散化+线段树上二分。。。 Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest G. Of Zorcs and Axes的更多相关文章
- 最小割 D. Behind the Wall Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest
题目链接:http://codeforces.com/gym/101149/problem/D 题目大意: 堡垒受到攻击.堡垒是n*m的矩阵,矩阵里刚开始都是平地,然后那个数值表示在当前平地上建一面墙 ...
- 几何+思维 Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest K. Revenge of the Dragon
题目链接:http://codeforces.com/gym/101149/problem/K 题目大意: 给你两个点a,b.一个人在a点,一个人在b点,b点的人要追杀a的点,他的跑步速度是a的两倍. ...
- 最短路+找规律 Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest L. Right Build
题目链接:http://codeforces.com/gym/101149/problem/L 题目大意:有n个点(其实是n+1个点,因为编号是0~n),m条有向边.起点是0,到a和b两个节点,所经过 ...
- ACM ICPC 2016–2017, NEERC, Northern Subregional Contest Problem J. Java2016
题目来源:http://codeforces.com/group/aUVPeyEnI2/contest/229510 时间限制:2s 空间限制:256MB 题目大意: 给定一个数字c 用 " ...
- LOJ 3059 「HNOI2019」序列——贪心与前后缀的思路+线段树上二分
题目:https://loj.ac/problem/3059 一段 A 选一个 B 的话, B 是这段 A 的平均值.因为 \( \sum (A_i-B)^2 = \sum A_i^2 - 2*B \ ...
- 【BZOJ】4293: [PA2015]Siano 线段树上二分
[题意]给定n棵高度初始为0的草,每天每棵草会长高a[i],m次收割,每次在d[i]天将所有>b[i]的草收割到b[i],求每次收割量.n<=500000. [算法]线段树上二分 [题解] ...
- hdu 5930 GCD 线段树上二分/ 强行合并维护信息
from NOIP2016模拟题28 题目大意 n个点的序列,权值\(<=10^6\) q个操作 1.单点修改 2.求所有区间gcd中,不同数个数 分析 1.以一个点为端点,向左或向右的gcd种 ...
- HDU 4747 Mex【线段树上二分+扫描线】
[题意概述] 一个区间的Mex为这个区间没有出现过的最小自然数,现在给你一个序列,要求求出所有区间的Mex的和. [题解] 扫描线+线段树. 我们在线段树上维护从当前左端点开始的前缀Mex,显然从左到 ...
- [NOIP2015模拟10.27] [JZOJ4270] 魔道研究 解题报告(动态开点+权值线段树上二分)
Description “我希望能使用更多的魔法.不对,是预定能使用啦.最终我要被大家称呼为大魔法使.为此我决定不惜一切努力.”——<The Grimoire of Marisa>雾雨魔理 ...
随机推荐
- 01—为什么使用java
Java解决的问题 1.指针问题 java里面没有指针,用引用解决指针问题,但是引用是一种限制的指针,不能参与整数运行和指向任意位置的内存,并且不用显示回收对象 引用地址:http://blog.cs ...
- 第三次c++作业
https://github.com/egoistor/3Elevators-scheduling 老实说,因为这周时间紧张,(高数的期中考和一些奇奇怪怪的时期), 所以代码大体是有,但是很多细节处理 ...
- 201621123037 《Java程序设计》第14周学习总结
作业14-数据库 标签(空格分隔): Java 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 使用数据库技术改造你的系统 2.1 简述如何使用数据库技术改造 ...
- 【Linux】- 简明Vim练习攻略
vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progress ...
- openssl 编程
背景: 生成私钥.公钥 --> 生成AES-key seed[32], iv[16] --> 公钥加密ASE-key, IV,传给Server --> Server用私钥解密,得到A ...
- 剖析Vue原理&实现双向绑定MVVM-2
vue.js 最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统.本文仅探究双向绑定是怎样实现的.先讲涉及的知识点,再用简化得不能再简化的代码实现一个简单的 hello world 示例. 一 ...
- 第190天:js---String常用属性和方法(最全)
String常用属性和方法 一.string对象构造函数 /*string对象构造函数*/ console.log('字符串即对象');//字符串即对象 //传统方式 - 背后会自动将其转换成对象 / ...
- 【明哥报错簿】之【解决eclipse项目小红叉】
解决方案: 0.如果是jdk版本不一致,直接右击项目名称,选择maven里面的update project.原因一般是maven的pom.xml里面设置的编译插件org.apache.maven.pl ...
- Contest 7
A:搜索好难啊根本不会啊. B:原题都能写挂没救了啊.考虑求出每个数作为最小值时能向左向右扩展到的最远位置,那么这段区间里的所有数就不可能作为唯一的最小值成为最优解了,否则假设可以的话这段区间里的数都 ...
- 题解 P1478 【陶陶摘苹果(升级版)】
看着你们累死累活得快排.冒泡.结构体特殊冒泡.还有dp... 蒟蒻表示真的不用那么麻烦! 难度:新手村+1 压行情况:0 理解难度:0 首先我们来了解一下优先队列:(自己抄的自己...) 讲元素一个个 ...