• 【二分+尺取】HDU 6119 小小粉丝度度熊


    http://acm.hdu.edu.cn/showproblem.php?pid=6119

    【思路】

    • 首先通过处理交叉的可以处理成不交叉的
    • 然后二分查找答案
    • 如何判断一个长度是否可行?
    • 双指针O(n)扫一次就可以,要处理区间和问题,所以先求前缀和
    • 时间复杂度O(nlogn)

    【AC】

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<string>
      5 #include<algorithm>
      6 #include<cmath>
      7 
      8 using namespace std;
      9 typedef long long ll;
     10 const int maxn=1e5+3;
     11 int n,m;
     12 int cnt1,cnt2;
     13 struct node
     14 {
     15     int l;
     16     int r;
     17 }a[maxn];
     18 int b[maxn];
     19 int c[maxn];
     20 int pre1[maxn];
     21 int pre2[maxn];
     22 
     23 bool cmp(node x,node y)
     24 {
     25     if(x.l!=y.l) return x.l<y.l;
     26     return x.r<y.r;
     27 }
     28 void Pre()
     29 {
     30     memset(pre1,0,sizeof(pre1));
     31     pre1[0]=b[0];
     32     for(int i=1;i<cnt1;i++)
     33     {
     34         pre1[i]=pre1[i-1]+b[i];
     35     }
     36     memset(pre2,0,sizeof(pre2));
     37     pre2[0]=c[0];
     38     for(int i=1;i<cnt2;i++)
     39     {
     40         pre2[i]=pre2[i-1]+c[i];
     41     }
     42     
     43 }
     44 bool check(int p,int q,int mid)
     45 {
     46     if(p==0) return pre1[q]>=mid;
     47     return pre1[q]-pre1[p-1]>=mid;
     48 }
     49 bool judge(int mid)
     50 {
     51     int pos=upper_bound(pre2,pre2+cnt2,m)-pre2-1;
     52     int totm=pre2[pos];
     53     int p=0,q=pos+1;
     54     while(p<=q&&q<cnt1)
     55     {
     56         if(check(p,q,mid))
     57         {
     58             return true;
     59         }
     60         else
     61         {
     62             totm-=c[p];
     63             p++;
     64             while(pos+1<cnt2&&totm+c[pos+1]<=m)
     65             {
     66                 totm+=c[pos+1];
     67                 pos++;
     68             }
     69             q=pos+1;
     70         }
     71     }
     72     return false;
     73 }
     74 int main()
     75 {
     76     while(scanf("%d%d",&n,&m)!=EOF)
     77     {
     78         for(int i=0;i<n;i++)
     79         {
     80             scanf("%d%d",&a[i].l,&a[i].r);
     81         }
     82         sort(a,a+n,cmp);
     83         cnt1=0;
     84         cnt2=0;
     85         int p=a[0].l,q=a[0].r;
     86         int low=0,high=0;
     87         for(int i=1;i<n;i++)
     88         {
     89             if(a[i].l<=q)
     90             {
     91                 q=max(q,a[i].r);
     92             }
     93             else
     94             {
     95                 b[cnt1++]=q-p+1;
     96                 high+=q-p+1;
     97                 c[cnt2++]=a[i].l-q-1;
     98                 p=a[i].l;
     99                 q=a[i].r;
    100             }
    101         }
    102         b[cnt1++]=q-p+1;
    103         high+=q-p+1;
    104         Pre();
    105         while(low<=high)
    106         {
    107             int mid=(low+high)>>1;
    108             if(judge(mid))
    109             {
    110                 low=mid+1;
    111             }
    112             else
    113             {
    114                 high=mid-1;
    115             }
    116         }
    117         cout<<low+m-1<<endl;
    118     }
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    cnpm镜像安装
    wxParse解析html
    C++回调函数
    QT源码分析:QTcpServer
    QT实现支持加密的Sqlite数据库引擎
    VS2013+OpenCV3.4.2编译
    Android Tcp操作
    使用Delphi开发linux应用
    QT5.10+MinGW+OpenCV3.4.2编译
    C++ ActiveX开发的问题讨论
  • 原文地址:https://www.cnblogs.com/itcsl/p/7354318.html
Copyright © 2020-2023  润新知