BZOJ 1178 APIO 2009 会议中心

提示:
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,倍增)