zoukankan      html  css  js  c++  java
  • [NOI2016]区间

    题目大意:
      有n次操作,每次覆盖数轴上的区间[l,r]。
      现在要你挑出m次操作,使得数轴上有一个整点恰好被覆盖m次,且最大覆盖区间与最小覆盖区间大小之差最小。

    思路:
      首先把询问按长度排序,然后用尺取法O(n)枚举左右端点,用线段树维护每个点被覆盖了几次。
      线段树中的修改要离散化,但最后算长度差时还是要按原来的长度算。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<vector>
     4 #include<algorithm>
     5 inline int getint() {
     6     register char ch;
     7     while(!isdigit(ch=getchar()));
     8     register int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int inf=0x7fffffff;
    13 const int N=500000;
    14 struct Modify {
    15     int l,r,b,e;
    16     bool operator < (const Modify &another) const {
    17         return r-l<another.r-another.l;
    18     }
    19 };
    20 Modify mod[N];
    21 std::vector<std::pair<int,int> > v;
    22 class SegmentTree {
    23     #define _left <<1
    24     #define _right <<1|1
    25     private:
    26         int val[N<<3],tag[N<<3];
    27         void push_down(const int &p) {
    28             tag[p _left]+=tag[p];
    29             tag[p _right]+=tag[p];
    30             val[p _left]+=tag[p];
    31             val[p _right]+=tag[p];
    32             tag[p]=0;
    33         }
    34         void push_up(const int &p) {
    35             val[p]=std::max(val[p _left],val[p _right]);
    36         }
    37     public:
    38         void modify(const int &p,const int &b,const int &e,const int &l,const int &r,const int &x) {
    39             if(b==l&&e==r) {
    40                 tag[p]+=x;
    41                 val[p]+=x;
    42                 return;
    43             }
    44             push_down(p);
    45             const int mid=(b+e)>>1;
    46             if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),x);
    47             if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r,x);
    48             push_up(p);
    49         }
    50         int max() const {
    51             return  val[1];
    52         }
    53     #undef _left
    54     #undef _right
    55 };
    56 SegmentTree t;
    57 int main() {
    58     const int n=getint(),m=getint();
    59     v.push_back(std::make_pair(-1,-1));
    60     for(register int i=0;i<n;i++) {
    61         v.push_back(std::make_pair(mod[i].l=getint(),i));
    62         v.push_back(std::make_pair(mod[i].r=getint(),i));
    63     }
    64     int cnt=0;
    65     std::sort(v.begin(),v.end());
    66     for(register unsigned i=1;i<v.size();i++) {
    67         if(v[i].first!=v[i-1].first) cnt++;
    68         if(mod[v[i].second].l==v[i].first) mod[v[i].second].b=cnt;
    69         if(mod[v[i].second].r==v[i].first) mod[v[i].second].e=cnt;
    70     }
    71     v.clear();
    72     std::sort(&mod[0],&mod[n]);
    73     int ans=inf;
    74     t.modify(1,1,cnt,mod[0].b,mod[0].e,1);
    75     for(register int l=0,r=1;l<r;l++) {
    76         while(t.max()<m&&r<n) {
    77             t.modify(1,1,cnt,mod[r].b,mod[r].e,1);
    78             r++;
    79         }
    80         if(r==n&&t.max()<m) break;
    81         ans=std::min(ans,(mod[r-1].r-mod[r-1].l)-(mod[l].r-mod[l].l));
    82         t.modify(1,1,cnt,mod[l].b,mod[l].e,-1);
    83     }
    84     printf("%d
    ",ans!=inf?ans:-1);
    85     return 0;
    86 }
  • 相关阅读:
    SQLServer2008安装卡在publishing assembly information
    找新朋友
    如何解决:Android中 Error generating final archive: Debug Certificate 的错误
    Open your mind
    A+B Format (20)
    A+B
    1005. Spell It Right (20)
    如何彻底卸载 SQL SERVER
    VC快捷键
    C#之将数据导出到Excel
  • 原文地址:https://www.cnblogs.com/skylee03/p/8202835.html
Copyright © 2011-2022 走看看