• UVa 12715 Watching the Kangaroo(二分)


    题意:n条线段(n <= 100000) (L<=R <= 1e9) ,m组询问(m <= 100000) 每次询问一个点的覆盖范围的最大值。一个点x对于一条包括其的线段,覆盖范围为min(x-L,R-x)

    思路:考虑将线段一份为二,对于左边的那部分,以右端点排序,然后 二分找到右端点恰好满足的那个点为id,那么接下来要做的就是就是在[id,n]这个范围内找到L最小的那个点,能够通过求前缀最大来得到。那么左边最大距离为  seg[id].L-preLMax[id],右边最大的求法也是类似。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <string>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    typedef long long LL;
    const int maxn = 100000+10;
    #define REP(_,a,b) for(int _ = (a); _ <= (b); _++)
    struct seg{
        int L,R;
        seg(int L = 0,int R = 0):L(L),R(R){}
    };
    bool cmp1(seg a,seg b) {
        if(a.R != b.R)  return a.R < b.R;
        else return a.L < b.L;
    }
    bool cmp2(seg a,seg b) {
        if(a.L != b.L)  return a.L < b.L;
        else return a.R < b.R;
    }
    vector<seg>lft,rgt;
    
    int preLMax[maxn],preRMax[maxn];
    int n,m;
    
    int main(){
    
        int ncase,T=1;
        cin >> ncase;
        while(ncase--) {
            lft.clear();
            rgt.clear();
            scanf("%d%d",&n,&m);
            for(int i = 0; i < n; i++) {
                int L,R;
                scanf("%d%d",&L,&R);
                int mid = (L+R)>>1;
                lft.push_back(seg(L,mid));
                rgt.push_back(seg(mid,R));
            }
    
            sort(lft.begin(),lft.end(),cmp1);
            preLMax[lft.size()] = 1e9;
            for(int i = lft.size()-1; i >= 0; i--) {
                preLMax[i] = min(preLMax[i+1],lft[i].L);
            }
            sort(rgt.begin(),rgt.end(),cmp2);
            preRMax[0] = rgt[0].R;
            for(int i = 1; i < rgt.size(); i++) {
                preRMax[i] = max(preRMax[i-1],rgt[i].R);
            }
            printf("Case %d:
    ",T++);
            while(m--) {
                int x,ans=0;
                scanf("%d",&x);
                int L = 0,R = lft.size()-1;
                while(L <= R) {
                    int mid = (L+R) >>1;
                    if(lft[mid].R < x) {
                        L = mid+1;
                    }else{
                        R = mid-1;
                    }
                }
                ans = max(ans,x-preLMax[L]);
                L = 0,R = rgt.size()-1;
                while(L <= R) {
                    int mid = (L+R) >>1;
                    if(rgt[mid].L < x) {
                        L = mid+1;
                    }else{
                        R = mid-1;
                    }
                }
                ans = max(ans,preRMax[R]-x);
                ans = max(ans,0);
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    


  • 相关阅读:
    基础MYSQl技巧集锦
    C MySQL float类型数据 用 printf()打印
    1Tomcat+Axis+Eclipse实例讲解 2自己做的一个可以用的webservice,只是开始 (WebService好文)
    信号量 进程 (m个生产者,n个消费者,容量为r的缓冲区)
    信号量和同步互斥
    C语言 wait()信号量部分 signal()信号量部分代码
    Tomcat+Axis+Eclipse实例讲解
    MySQL 集合 补集
    SELECT DocID, SUM(a.Score + B.Score) AS TOTAL Itemset_ONE a LEFT Join Itemset_Two b ON a.DocID=b.DocID 太慢
    Yii AR Model 查询
  • 原文地址:https://www.cnblogs.com/jhcelue/p/6751655.html
Copyright © 2020-2023  润新知