Interval query

题意:

给出数轴上的N个区间,M个询问"QUERY(a, b)", 意为[a, b]之间不相交的集合的最大数量是多少。

 

解法:

考虑 $O(n)$ 的贪心做法,预处理出对于每一个位置$i$,满足$i \leq L_j$ 的 $R_j$的最小值

这样暴力向后找即可。

用倍增优化这个过程 $O(nlogn)$

 

#include <bits/stdc++.h> 

#define N 100010

using namespace std;


struct node
{
    int l,r; 
}a[N],q[N];

int n,m,tot0;
int a0[N<<2];
int minR[N<<2][21];

bool cmp(node a,node b)
{
    return a.l<b.l;
}

int ask(int l,int r)
{
    int x = l,ans = 0;
    for(int i=20;~i;i--)
        if(minR[x][i] <= r)
            x = minR[x][i], ans += (1<<i);
    return ans;
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        a0[0] = 0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a0[++a0[0]] = a[i].l;
            a0[++a0[0]] = a[i].r;
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&q[i].l,&q[i].r);
            a0[++a0[0]] = q[i].l;
            a0[++a0[0]] = q[i].r;
        }
        sort(a0+1,a0+a0[0]+1);
        tot0=1;
        for(int i=2;i<=a0[0];i++) if(a0[i]!=a0[i-1]) a0[++tot0] = a0[i];
        for(int i=1;i<=n;i++)
        {
            a[i].l = lower_bound(a0+1,a0+tot0+1,a[i].l) - a0;
            a[i].r = lower_bound(a0+1,a0+tot0+1,a[i].r) - a0;
        }
        sort(a+1,a+n+1,cmp);
        int j=n,tmpR = tot0+1;
        for(int i=tot0;i>=1;i--)
        {
            while(j>0 && a[j].l >= i)
            {
                tmpR = min(tmpR, a[j].r);
                j--;
            }
            minR[i][0] = tmpR;
        }
        for(int t=1;t<=20;t++)
            for(int i=1;i<=tot0;i++)
            {
                if(minR[i][t-1]<=tot0)
                    minR[i][t] = minR[minR[i][t-1]][t-1];
                else minR[i][t] = tot0+1;
            }
        for(int i=1;i<=m;i++)
        {
            q[i].l = lower_bound(a0+1,a0+tot0+1,q[i].l) - a0;
            q[i].r = lower_bound(a0+1,a0+tot0+1,q[i].r) - a0;
            printf("%d\n",ask(q[i].l,q[i].r));
        }
    }
    return 0;
}
View Code

 

posted @ 2017-05-09 20:09  lawyer'  阅读(247)  评论(0编辑  收藏  举报