zoukankan      html  css  js  c++  java
  • [TJOI2016][HEOI2016]排序

    题目大意:
      给定一个$1sim n(nleq10^5)$的全排列,有$m(mleq10^5)$次操作,每次把区间$[l,r]$按照升序或降序排序。最后询问所有操作完成后,位置为$q$的数是多少。

    思路:
      题目只需要求位置为$q$的数是多少,而并不关心其他的数是多少。因此排序时也只需要考虑答案的那个数。二分答案$k$,将$<k$的数当成0,$geq k$的数当成1,原序列就变成了一个01序列。这样排序时只需要统计区间内0和1的个数,线段树区间修改即可。若排序后$q$上的值为1,则答案$geq k$,否则$<k$。

      1 #include<cstdio>
      2 #include<cctype>
      3 #include<algorithm>
      4 inline int getint() {
      5     register char ch;
      6     while(!isdigit(ch=getchar()));
      7     register int x=ch^'0';
      8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
      9     return x;
     10 }
     11 const int N=100001,M=100000;
     12 int n,m,q,a[N];
     13 struct Modify {
     14     bool type;
     15     int l,r;
     16 };
     17 Modify o[M];
     18 class SegmentTree {
     19     #define _left <<1
     20     #define _right <<1|1
     21     private:
     22         int val[N<<2],tag[N<<2];
     23         void push_up(const int &p) {
     24             val[p]=val[p _left]+val[p _right];
     25         }
     26         void push_down(const int &p,const int &b,const int &e) {
     27             if(tag[p]==-1) return;
     28             const int mid=(b+e)>>1;
     29             tag[p _left]=tag[p _right]=tag[p];
     30             val[p _left]=tag[p]*length(b,mid);
     31             val[p _right]=tag[p]*length(mid+1,e);
     32             tag[p]=-1;
     33         }
     34         int length(const int &b,const int &e) const {
     35             return e-b+1;
     36         }
     37     public:
     38         void build(const int &p,const int &b,const int &e,const int &k) {
     39             if(b==e) {
     40                 val[p]=a[b]>=k;
     41                 return;
     42             }
     43             tag[p]=-1;
     44             const int mid=(b+e)>>1;
     45             build(p _left,b,mid,k);
     46             build(p _right,mid+1,e,k);
     47             push_up(p);
     48         }
     49         void modify(const int &p,const int &b,const int &e,const int &l,const int &r,const bool &x) {
     50             if(b==l&&e==r) {
     51                 tag[p]=x;
     52                 val[p]=x*length(b,e);
     53                 return;
     54             }
     55             push_down(p,b,e);
     56             const int mid=(b+e)>>1;
     57             if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),x);
     58             if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r,x);
     59             push_up(p);
     60         }
     61         int query(const int &p,const int &b,const int &e,const int &l,const int &r) {
     62             if(b==l&&e==r) return val[p];
     63             push_down(p,b,e);
     64             const int mid=(b+e)>>1;
     65             int ret=0;
     66             if(l<=mid) ret+=query(p _left,b,mid,l,std::min(mid,r));
     67             if(r>mid) ret+=query(p _right,mid+1,e,std::max(mid+1,l),r);
     68             return ret;
     69         }
     70     #undef _left
     71     #undef _right
     72 };
     73 SegmentTree t;
     74 inline bool check(const int &k) {
     75     t.build(1,1,n,k);
     76     for(register int i=0;i<m;i++) {
     77         const int opt=o[i].type,l=o[i].l,r=o[i].r,cnt1=t.query(1,1,n,l,r),cnt0=r-l+1-cnt1;
     78         if(opt==0) {
     79             if(cnt0) t.modify(1,1,n,l,l+cnt0-1,0);
     80             t.modify(1,1,n,l+cnt0,r,1);
     81         }
     82         if(opt==1) {
     83             if(cnt1) t.modify(1,1,n,l,l+cnt1-1,1);
     84             t.modify(1,1,n,l+cnt1,r,0);
     85         }
     86     }
     87     return t.query(1,1,n,q,q);
     88 }
     89 int main() {
     90     n=getint(),m=getint();
     91     for(register int i=1;i<=n;i++) a[i]=getint();
     92     for(register int i=0;i<m;i++) {
     93         const int opt=getint(),l=getint(),r=getint();
     94         o[i]=(Modify){opt,l,r};
     95     }
     96     q=getint();
     97     int l=1,r=n;
     98     while(l<=r) {
     99         const int mid=(l+r)>>1;
    100         if(check(mid)) {
    101             l=mid+1;
    102         } else {
    103             r=mid-1;
    104         }
    105     }
    106     printf("%d
    ",l-1);
    107     return 0;
    108 }
  • 相关阅读:
    ue4 Windows RawInput Plugin
    UE4 VR中一种比较清晰的UI制作方式
    C# 自定义特性及反射
    C# 委托
    java+orace+hql分页
    数据库小知识总结
    往oracle数据库表中插入五十万条数据
    jsp页面传到action乱码问题
    常见数据库对象与java.sql.Types对照
    Oracle数据库初探
  • 原文地址:https://www.cnblogs.com/skylee03/p/8526908.html
Copyright © 2011-2022 走看看