http://www.lydsy.com/JudgeOnline/problem.php?id=1178

这道题想了好久没想明白,倍增数组通过看题解很快就明白了,但是一小段区间内应有的最多线段数一直不知道怎么记录。

后来聪哥提醒我才明白,直接getans(l,r)不就完了吗_(:з」∠)_根本不用记录啊QwQ

我用splay维护线段的位置顺序,查找前驱后继等等。
上午因为懒得写插入线段前判断线段将要覆盖的区间是否是空的,所以又写了一棵线段树。然后因为一个自以为是线段树写残了的错误,就把线段树删了QAQ

后来才知道那个错误是因为代码宽度很大以至于最右边被遮住的一个部分因为减号打成了加号调了一下午(/= _ =)/~┴┴,最后还是写了splay查找前驱后继,调了一天了QAQ。我竟然把这种题当代码题做了!

最后,最后一条线段的编号后面不能有空格,否则会PE

时间复杂度$O(nlogn)$

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 200003;
int in() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = (k << 3) + (k << 1) + c - '0';
return k * fh;
} struct Line {
int l, r;
bool operator < (const Line &A) const {
return r == A.r ? l > A.l : r < A.r;
}
} L[N], Lf[N], F[N], lth, rth;
int right[N << 1], cnt = 0, H[N << 1], n, tot, f[N][19], ans; int getans(int l, int r) {
l = right[l - 1]; int ret = 0;
for(int j = 18; j >= 0; --j)
if (f[l][j] <= r && f[l][j] != 0) {
ret += (1 << j);
l = right[f[l][j]];
}
return ret;
} namespace Splay {
struct node *null;
struct node {
node *ch[2], *fa;
int l, r, s;
node(int left = 0, int right = 0) {
ch[0] = ch[1] = fa = null;
l = left; r = right; s = 1;
}
bool pl() {return fa->ch[1] == this;}
void setc(node *r, bool c) {ch[c] = r; r->fa = this;}
void count() {s = ch[0]->s + ch[1]->s + 1;}
} *root;
void rotate(node *r) {
node *f = r->fa;
bool c = r->pl();
if (f == root) root = r, r->fa = null;
else f->fa->setc(r, f->pl());
f->setc(r->ch[!c], c);
r->setc(f, !c);
f->count();
}
void splay(node *r, node *tar = null) {
for(; r->fa != tar; rotate(r))
if (r->fa->fa != tar) rotate(r->pl() == r->fa->pl() ? r->fa : r);
r->count();
}
void insert(int l, int r) {
bool c; node *now = root;
if (root == null) {
root = new node(l, r);
return;
}
while (1) {
if (l > now->r) c = true;
else if (r < now->l) c = false;
if (now->ch[c] == null) {
now->setc(new node(l, r), c);
splay(now->ch[c]);
return;
} else now = now->ch[c];
}
}
void init(int l, int r) {
null = new node();
null->ch[0] = null->ch[1] = null->fa = null;
null->s = 0;
root = null;
insert(l, l); insert(r, r);
}
Line query_l(node *now, int l, int tmp) {
if (now == null) return (Line) {0, -0x7fffffff};
if (now->r >= l) return query_l(now->ch[0], l, tmp);
else {
tmp += now->ch[0]->s + 1;
return max((Line) {tmp, now->r}, query_l(now->ch[1], l, tmp));
}
}
Line query_r(node *now, int r, int tmp) {
if (now == null) return (Line) {cnt, 0x7fffffff};
if (now->l <= r) return query_r(now->ch[1], r, tmp + now->ch[0]->s + 1);
else return min((Line) {tmp + now->ch[0]->s + 1, now->l}, query_r(now->ch[0], r, tmp));
}
} int main() {
n = in();
for(int i = 1; i <= n; ++i) {
L[i].l = in(); L[i].r = in();
H[++cnt] = L[i].l; H[++cnt] = L[i].r;
}
sort(H + 1, H + cnt + 1);
cnt = unique(H + 1, H + cnt + 1) - H;
for(int i = 1; i <= n; ++i) {
L[i].l = lower_bound(H + 1, H + cnt, L[i].l) - H;
L[i].r = lower_bound(H + 1, H + cnt, L[i].r) - H;
F[i] = L[i];
}
sort(L + 1, L + n + 1); Lf[tot = 1] = L[1];
for(int i = 2; i <= n; ++i)
if (L[i].l > Lf[tot].l)
Lf[++tot] = L[i];
Lf[tot + 1].l = 0x7fffffff; int head, tail = tot;
for(head = cnt - 1; head > 0; --head) {
while (head < Lf[tail].l) --tail;
right[head] = tail + 1;
}
right[0] = 1; for(int i = 1; i <= tot; ++i) f[i][0] = Lf[i].r;
for(int j = 1; j <= 18; ++j)
for(int i = 1; i <= tot; ++i) {
if (f[i][j - 1] == 0 || (head = f[right[f[i][j - 1]]][j - 1]) == 0) continue;
f[i][j] = head;
} Splay::init(0, cnt);
printf("%d\n", (ans = getans(1, cnt - 1)));
int l, r;
for(int i = 1; i <= n; ++i) {
lth = Splay::query_l(Splay::root, F[i].l, 0);
rth = Splay::query_r(Splay::root, F[i].r, 0);
if (rth.l - lth.l != 1) continue;
l = lth.r; r = rth.r;
if (getans(l + 1, F[i].l - 1) + getans(F[i].r + 1, r - 1) + 1 == getans(l + 1, r - 1)) {
printf("%d", i);
Splay::insert(F[i].l, F[i].r);
--ans;
if (ans) putchar(' ');
}
} puts("");
return 0;
}

【BZOJ 1178】【APIO 2009】CONVENTION会议中心的更多相关文章

  1. 【BZOJ】【1178】【APIO2009】convention会议中心

    贪心 如果不考虑字典序的话,直接按右端点排序,能选就选,就可以算出ans…… 但是要算一个字典序最小的解就比较蛋疼了= = Orz了zyf的题解 就是按字典序从小到大依次枚举,在不改变答案的情况下,能 ...

  2. 1178: [Apio2009]CONVENTION会议中心

    1178: [Apio2009]CONVENTION会议中心 https://lydsy.com/JudgeOnline/problem.php?id=1178 分析: set+倍增. 首先把所有有包 ...

  3. 【BZOJ-1178】CONVENTION会议中心 倍增 + set (神思路好题!)

    1178: [Apio2009]CONVENTION会议中心 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 812  Solved: 323[Subm ...

  4. bzoj1178 [Apio2009]CONVENTION会议中心 区间dp+贪心

    [Apio2009]CONVENTION会议中心 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1130  Solved: 444[Submit][S ...

  5. BZOJ1178 [Apio2009]CONVENTION会议中心

    本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! Description Siruseri政府建造了 ...

  6. bzoj 1178: [Apio2009]CONVENTION会议中心(少见做法掉落!)【贪心+二分】

    数组若干+手动二分一个的算法,bzoj rank8 ===============================废话分割线=================================== 我我 ...

  7. bzoj 1178 [Apio2009]CONVENTION会议中心

    这题好难啊! 我好菜啊! 思路:对于最多线段不相交, 我们可以按左端点sort之后,贪心取. 但是这个题要求选取的线段排序之后序号的字典序最小. 那么我们如果按序号贪心地从大往小往里放, 那么对于第k ...

  8. 【bzoj1178】 Apio2009—CONVENTION会议中心

    http://www.lydsy.com/JudgeOnline/problem.php?id=1178 (题目链接) 题意 给出n个区间,问在区间两两不相交的情况下最多能选出多少区间,并输出字典序最 ...

  9. bzoj 1179 [APIO 2009]Atm(APIO水题) - Tarjan - spfa

    Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一 ...

随机推荐

  1. IntelliJ IDEA 将 Maven 构建的 Java 项目打包

    前言 IntelliJ IDEA 编译生成 Jar 包的方式与 Eclipse 不同,如何将此 Maven 构建 Java 推荐引擎项目生成 Jar 包确实搜索了不少资料,有成功的有失败的,特将此验证 ...

  2. 详细说说 Google Test Certified 的各级——Level 2,3

    转载请联系作者,谢谢!   No releases with red tests基于Level1搭建的持续集成,持续发布选用的CL(changelist)就可以取自CI系统最后跑通的CL,因为持续集成 ...

  3. openjudge8469特殊密码锁[贪心]

    描述 有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态. 然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转.当然,如果你 ...

  4. 关于反射blog

    非常好的Java反射例子   疯狂java   在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走在最前方,更多Java学习,请浏览疯狂java ...

  5. pitch yaw roll 的区别

    http://blog.163.com/vipwdp@126/blog/static/150224366201281935518196/

  6. java 25 - 4 网络编程之 UDP协议传输思路

    UDP传输 两个类:DatagramSocket与DatagramPacket(具体看API) A:建立发送端,接收端. B:建立数据包. C:调用Socket的发送接收方法. D:关闭Socket. ...

  7. ADB server didn't ACK 问题解决

    在命令行中运行adb shell 出现如下错误提示 C:\Documents and Settings\Administrator>adb shelladb server is out of d ...

  8. Java核心技术点之动态代理

    本篇博文会从代理的概念出发,介绍Java中动态代理技术的使用,并进一步探索它的实现原理.由于个人水平有限,叙述中难免出现不清晰或是不准确的地方,希望大家可以指正,谢谢大家:) 一.概述 1. 什么是代 ...

  9. HTML5添加 video 视频标签后仍然无法播放的解决方法 IIS添加MIEI类型

    现象:插入如下代码后仍然无法看视频(注:视频已确认为浏览器支持格式) <video controls="controls" width="500px" h ...

  10. centos6 pyotp bug修复

    yum install python-pip -ypip install pyotp vim /usr/lib/python2.6/site-packages/pyotp/utils.py... 49 ...