ZOJ 3953 Intervals

线段树,排序。

按照$R$从小到大排序之后逐个检查,如果$L$,$R$最大值不超过$2$,那么就把这个区间放进去,区间$+1$,否则不能放进去。

#include<bits/stdc++.h>
using namespace std;

int T,n,sz;
int a[100010];
struct X { int L,R,id; }s[50010];
int f[400010],m[400010];
int P;

bool cmp(X a,X b)
{
    return a.R<b.R;
}

int get(int x)
{
    int ll=1,rr=sz,res;
    while(ll<=rr)
    {
        int mid = (ll+rr)/2;
        if(a[mid]>x) rr=mid-1;
        else if(a[mid]==x) return mid;
        else ll=mid+1;
    }
}

void pushDown(int rt)
{
    if(f[rt]==0) return ;
    f[2*rt]+=f[rt];
    f[2*rt+1]+=f[rt];
    m[2*rt]+=f[rt];
    m[2*rt+1]+=f[rt];
    f[rt]=0;
}

void update(int L,int R,int val,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        f[rt]+=val;
        m[rt]+=val;
        return ;
    }

    pushDown(rt);
    int mid = (l+r)/2;
    if(L<=mid) update(L,R,val,l,mid,2*rt);
    if(R>mid) update(L,R,val,mid+1,r,2*rt+1);
    m[rt] = max(m[2*rt],m[2*rt+1]);
}

void query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        P=max(P,m[rt]);
        return ;
    }

    pushDown(rt);
    int mid = (l+r)/2;
    if(L<=mid) query(L,R,l,mid,2*rt);
    if(R>mid) query(L,R,mid+1,r,2*rt+1);
    m[rt] = max(m[2*rt],m[2*rt+1]);
}

void build(int l,int r,int rt)
{
    m[rt] = 0;
    f[rt] = 0;
    if(l==r) return ;

    int mid = (l+r)/2;
    build(l,mid,2*rt);
    build(mid+1,r,2*rt+1);
}

int ans[50010],q;

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        sz=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&s[i].L,&s[i].R);
            sz++; a[sz]=s[i].L;
            sz++; a[sz]=s[i].R;
        }

        sort(a+1,a+1+sz);

        for(int i=1;i<=n;i++)
        {
            s[i].L=get(s[i].L);
            s[i].R=get(s[i].R);
            s[i].id=i;
        }

        sort(s+1,s+1+n,cmp);

        q=0;

        build(1,sz,1);

        for(int i=1;i<=n;i++)
        {
            P=0;
            query(s[i].L,s[i].R,1,sz,1);
            if(P==2)
            {
                ans[q++]=s[i].id;
                continue;
            }
            else update(s[i].L,s[i].R,1,1,sz,1);
        }

        sort(ans,ans+q);
        printf("%d
",q);
        for(int i=0;i<q;i++)
        {
            printf("%d",ans[i]);
            if(i<q-1) printf(" ");
        }
        printf("
");

    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/6690948.html