您的位置:首页 > 其它

BZOJ 1178 APIO 2009 会议中心

2016-02-21 16:27 369 查看
提示:

1. NOIP开车旅行做过的小伙伴肯定能搞定此题

这个题目网上题解很多 , 这里不赘述 , 提供一个可读一些的代码实现:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <stack>
#include <queue>
#include <algorithm>
#include <set>

using namespace std;
const int INF = 0x3f3f3f3f;

inline int re() {
int n = 0, ch = getchar(); bool flag = false;
while(!isdigit(ch)) flag |= ch == '-', ch = getchar();
while(isdigit(ch)) n = n * 10 + ch - '0', ch = getchar();
return flag ? -n : n;
}

const int maxn = 2e5+1e2;

struct seg
{
int l , r;
seg(int l=0,int r=0):l(l),r(r){}
void read() { l = re(); r = re(); }
bool operator <(const seg& b)const { return r<b.r || (r==b.r && l>b.l); }
};

int n , cnt;
seg a[maxn] , b[maxn];
int x[maxn] , y[maxn];

int Next[maxn][20];

int count(int l , int r)
{
int c = lower_bound(x+1, x+1+cnt, l)-x;

if(y[c]>r || c>cnt) return 0;

int res = 1;
for(int i=19;i>=0;i--) if(Next[c][i] && y[Next[c][i]]<=r) res+= 1<<i , c = Next[c][i];
return res;
}

int main(int argc, char *argv[]) {

cin>>n;
for(int i=1;i<=n;i++) a[i].read() , b[i] = a[i];

sort(b+1, b+1+n);
for(int i=1;i<=n;i++)
if(!cnt || b[i].l>b[cnt].l) b[++cnt] = b[i];
for(int i=1;i<=cnt;i++) x[i] = b[i].l , y[i] = b[i].r;

for(int i=1 , j=1;i<=cnt;i++)
{
while(j<=cnt && b[j].l <= b[i].r) j++;
Next[i][0] = (j==cnt+1?0:j);
}

for(int i=1;i<20;i++) for(int j=1;j<=cnt;j++)
{
int a = Next[j][i-1];
if(!a) continue;
Next[j][i] = Next[a][i-1];
}

cout<<count(-INF, INF)<<endl;

set<seg> comp;

comp.insert(seg(-INF , -INF));
comp.insert(seg(INF  ,  INF));

for(int i=1;i<=n;i++)
{
set<seg>::iterator p = comp.lower_bound(a[i]) , q;
q = p; q--;

int k1 = q->r , k2 = a[i].l , k3 = a[i].r , k4 = p->l;
if(k3 >= k4 || k2 <= k1) continue;

if(count(k1+1, k4-1) == count(k1+1, k2-1)+1+count(k3+1, k4-1))
{
printf("%d " , i);
comp.insert(a[i]);
}
}

return 0;
}


详细题解推荐Vincent的博客:

会议中心
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  APIO 倍增