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. AC日记——向量点积计算 openjudge 1.6 09

    09:向量点积计算 总时间限制:  1000ms 内存限制:  65536kB 描述 在线性代数.计算几何中,向量点积是一种十分重要的运算. 给定两个n维向量a=(a1,a2,...,an)和b=(b ...

  2. webstorm的中文教程和技巧分享

    webstorm是一款前端javascript开发编辑的神器,此文介绍webstorm的中文教程和技巧分享.webstorm8.0.3中文汉化版下载:百度网盘下载:http://pan.baidu.c ...

  3. [No00000A]计算机的存储单位

    位 bit (比特)(Binary Digits):存放一位二进制数,即 0 或 1,最小的存储单位. 字节 byte:8个二进制[bit (比特)(Binary Digits)]位为一个字节(B), ...

  4. Samsung I9103刷cm-10.1的方法

    按照官方网站的说明一步一步的做下去的时候发现在执行heimdall.exe文件的时候出现“不是win32的应用程序”的错误提示,因此决定按照其它方法安装recovery,然后再刷入CM10.1. sa ...

  5. Window 对象

    Window 对象 Window 对象表示浏览器中打开的窗口. 如果文档包含框架(<frame> 或 <iframe> 标签),浏览器会为 HTML 文档创建一个 window ...

  6. win10显示此电脑

    http://jingyan.baidu.com/article/3aed632e00dfe17011809169.html

  7. java多线程系类:基础篇:07线程休眠

    概要 本章,会对Thread中sleep()方法进行介绍.涉及到的内容包括:1. sleep()介绍2. sleep()示例3. sleep() 与 wait()的比较 转载请注明出处:http:// ...

  8. quartz.net 项目无法加载的问题

    最近尝试试用一下quartz.net 做任务调度用. 下载了源代码后打开解决方案发现项目无法加载.错误如下 未找到导入的项目“C:\Users\****\Desktop\Quartz.NET-2.1. ...

  9. python数字图像处理(15):霍夫线变换

    在图片处理中,霍夫变换主要是用来检测图片中的几何形状,包括直线.圆.椭圆等. 在skimage中,霍夫变换是放在tranform模块内,本篇主要讲解霍夫线变换. 对于平面中的一条直线,在笛卡尔坐标系中 ...

  10. Java 基础【11】@注解

    1.注解简介 JDK 1.5 中引入的 java.lang.annotation 包提供注解编程支持,可以让类在编译.类加载.运行时被读取,并执行相应的处理. 在 Java EE应用的时候,总是免不了 ...