zoukankan      html  css  js  c++  java
  • 刷题总结——Interval query(hdu4343倍增+贪心)

    题目:

    Problem Description

    This is a very simple question. There are N intervals in number axis, and M queries just like “QUERY(a,b)” indicate asking the maximum number of the disjoint intervals between (a,b) .

    Input

    There are several test cases. For each test case, the first line contains two integers N, M (0<N, M<=100000) as described above. In each following N lines, there are two integers indicate two endpoints of the i-th interval. Then come M lines and each line contains two integers indicating the endpoints of the i-th query.
    You can assume the left-endpoint is strictly less than the right-endpoint in each given interval and query and all these endpoints are between 0 and 1,000,000,000.

    Output

    For each query, you need to output the maximum number of the disjoint intervals in the asked interval in one line.

    Sample input

    3 2 1 2 2 3 1 3 1 2 1 3

    Sample Output

    1 2

    Author

    HIT

    Source

     

    题解:

      首先容易想到那些覆盖了其他较小区间的区间是可以忽略的··因为对于每个询问要尽量多取区间···

      然后考虑对于每个询问···我们肯定会采取贪心策略,从询问范围的左端开始找··如果找到一个区间就取该区间··然后跳到该区间的右端··再继续向右边找下一个区间··这个方法肯定是最优的····

      至于如何寻找,我们考虑倍增(现在发现关于区间的一些查询问题如果用数据结构解决不了的话基本上就是倍增了··),用g[i][j]表示从i点出发··在找到2^j个互不相交的区间后到达的最右端点··首先预处理g[i][0],然后再一次处理g[i][1],g[i][2]....即可

      最后对于每个询问我们像找lca那样跳区间··边跳边更新答案就可以了

    代码:

      

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int N=2e5+5;
    inline int R(){
        char c;int f=0;
        for(c=getchar();c<'0'||c>'9';c=getchar());
        for(;c<='9'&&c>='0';c=getchar())    f=(f<<3)+(f<<1)+c-'0';
        return f;
    }
    struct node{int l,r;}a[N],q[N],c[N];
    int b[N*2],cnt,n,m,stack[N],top=0,bel[N*2],g[N*2][25];
    inline void lsh(){
        sort(b+1,b+cnt+1);
        cnt=unique(b+1,b+cnt+1)-b-1;
        for(int i=1;i<=n;i++){
            a[i].l=lower_bound(b+1,b+cnt+1,a[i].l)-b;
            a[i].r=lower_bound(b+1,b+cnt+1,a[i].r)-b;
        }
        for(int i=1;i<=m;i++){
            q[i].l=lower_bound(b+1,b+cnt+1,q[i].l)-b;
            q[i].r=lower_bound(b+1,b+cnt+1,q[i].r)-b;
        }
    }
    inline bool cmp(node a,node b){
        if(a.l==b.l)  return a.r>b.r;
        else  return a.l<b.l;
    }
    inline void pre(){
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++){
            while(top&&a[i].l>=a[stack[top]].l&&a[i].r<=a[stack[top]].r)  top--;
            stack[++top]=i;
        }
        n=0;
        for(int i=1;i<=top;i++)    c[++n]=a[stack[i]];
        int tail=1;
        for(int i=1;i<=n;i++){
            while(tail<=c[i].l)    g[tail][0]=c[i].r,tail++;
        }
    }
    inline int query(int l,int r){
        int ans=0,i=l;
        for(int j=20;j>=0;j--)
            if(g[i][j]&&g[i][j]<=r)    i=g[i][j],ans+=(1<<j);
        return ans;
    }
    int main(){
        //freopen("a.in","r",stdin);
        while(scanf("%d%d",&n,&m)!=EOF){ 
            top=cnt=0;memset(g,0,sizeof(g));
            for(int i=1;i<=n;i++)    a[i].l=R(),a[i].r=R(),b[++cnt]=a[i].l,b[++cnt]=a[i].r;
            for(int i=1;i<=m;i++)    q[i].l=R(),q[i].r=R(),b[++cnt]=q[i].l,b[++cnt]=q[i].r;
            lsh();pre();
            for(int i=1;i<=20;i++)
                for(int j=1;j<=cnt;j++)    g[j][i]=g[g[j][i-1]][i-1];
            for(int i=1;i<=m;i++)    cout<<query(q[i].l,q[i].r)<<endl;
            
        }
        return 0;
    }
  • 相关阅读:
    安装xshell6
    eclipse的安装和汉化
    collectd+infludb+grafana实现tomcat JVM监控
    百度网站统计和CNZZ网站统计对比
    shell,计算指定行的和,计算指定列的和
    我为什么要写博客
    kafka监控之topic的lag情况监控
    用rundeck启动tomcat报错
    xwiki升级8.8.4
    矩阵掩膜操作
  • 原文地址:https://www.cnblogs.com/AseanA/p/7768243.html
Copyright © 2011-2022 走看看