• 洛谷P2824 [HEOI2016/TJOI2016]排序——题解


    P2824 [HEOI2016/TJOI2016]排序

    在在线算法的角度思考,发现序列排序的复杂度如何也难以简化(否则想出来的简化办法就进教科书了),故尝试从离线算法的角度思考。

    尝试思考二分。二分在大部分情况下都能将模型大程度简化(或说二分多提供了一个限制性条件,将各种奇怪的问题简化为判定性问题,毕竟“能不能”和“怎么才能”这两种问题的难度大部分情况下是完全不同的吧),对于二分的答案mid,按与mid的大于等于/小于的关系将序列转化为01数列,发现给一段01序列排序只需log n的时间复杂度。故有做法:

    注意一段区间的1的个数cnt可能为0,这时对于线段树的修改操作的区间会发生区间左端点大于右端点的诡异情形,故需特判,否则RE。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 
      5 #define dmid ((l+r)>>1)
      6 
      7 using namespace std;
      8 
      9 const int N=1e5+5;
     10 
     11 int n,m,a[N],ans,Mid,tre[N<<2],mod[N][3],q;
     12 
     13 bool lzy[N<<2],sig[N<<2];
     14 
     15 inline int read()
     16 {
     17     int x=0;
     18     char ch=getchar();
     19     while(!isdigit(ch))
     20         ch=getchar();
     21     while(isdigit(ch))
     22         x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
     23     return x;
     24 }
     25 
     26 void build(int t,int l,int r)
     27 {
     28     if(l==r)
     29     {
     30         tre[t]=(a[l]>=Mid);
     31         return;
     32     }
     33     int mid=(l+r)>>1;
     34     build(t<<1,l,mid);
     35     build((t<<1)+1,mid+1,r);
     36     tre[t]=tre[t<<1]+tre[(t<<1)+1];
     37 }
     38 
     39 inline void down(int t,int l,int r)
     40 {
     41     if(!lzy[t])
     42         return;
     43     int mid=(l+r)>>1;
     44     lzy[t<<1]=lzy[(t<<1)+1]=1;
     45     sig[t<<1]=sig[(t<<1)+1]=sig[t];
     46     tre[t<<1]=(mid-l+1)*sig[t];
     47     tre[(t<<1)+1]=(r-mid)*sig[t];
     48     lzy[t]=0;
     49 }
     50 
     51 int query(int t,int l,int r,int ll,int rr)
     52 {
     53     if(ll<=l&&r<=rr)
     54         return tre[t];
     55     down(t,l,r);
     56     int mid=(l+r)>>1;
     57     if(ll<=mid)
     58     {
     59         if(rr>mid)
     60             return query(t<<1,l,mid,ll,rr)+query((t<<1)+1,mid+1,r,ll,rr);
     61         else
     62             return query(t<<1,l,mid,ll,rr);
     63     }
     64     else
     65         return query((t<<1)+1,mid+1,r,ll,rr);
     66 }
     67 
     68 void modify(int t,int l,int r,int ll,int rr,int x)
     69 {
     70     if(ll<=l&&r<=rr)
     71     {
     72         lzy[t]=1;
     73         sig[t]=x;
     74         tre[t]=(r-l+1)*x;
     75         return;
     76     }
     77     down(t,l,r);
     78     if(ll<=dmid)
     79         modify(t<<1,l,dmid,ll,rr,x);
     80     if(rr>dmid)
     81         modify((t<<1)+1,dmid+1,r,ll,rr,x);
     82     tre[t]=tre[t<<1]+tre[(t<<1)+1];
     83 }
     84 
     85 inline int check()
     86 {
     87     build(1,1,n);
     88     memset(lzy,0,sizeof lzy);
     89     int cnt,ll,rr;
     90     for(int i=1;i<=m;++i)
     91     {
     92         ll=mod[i][1],rr=mod[i][2];
     93         cnt=query(1,1,n,ll,rr);
     94         if(mod[i][0])
     95         {
     96             if(cnt)
     97                 modify(1,1,n,ll,ll+cnt-1,1);
     98             modify(1,1,n,ll+cnt,rr,0);
     99         }
    100         else
    101         {
    102             modify(1,1,n,ll,rr-cnt,0);
    103             if(cnt)
    104                 modify(1,1,n,rr-cnt+1,rr,1);
    105         }
    106     }
    107     return query(1,1,n,q,q);
    108 }
    109 
    110 int main()
    111 {
    112     n=read();m=read();
    113     for(int i=1;i<=n;++i)
    114         a[i]=read();
    115     for(int i=1;i<=m;++i)
    116         mod[i][0]=read(),mod[i][1]=read(),mod[i][2]=read();
    117     q=read();
    118     int l=1,r=n;
    119     while(l<=r)
    120     {
    121         Mid=(l+r)>>1;
    122         if(check())
    123         {
    124             ans=Mid;
    125             l=Mid+1;
    126         }
    127         else
    128             r=Mid-1;
    129     }
    130     cout<<ans;
    131     return 0;
    132 }

    参考资料:

    题解 P2824 【[HEOI2016]排序】

  • 相关阅读:
    5.11-上位机重新编程
    3.30-计算机系统互联方案
    3.25-两个操作者的通信模式
    3.23-重新定义操作者框架
    go 修改数组中对象的值不生效的解决方法
    go orm QueryTable Filter 不生效解决方法
    Beego orm.Install() 插入 [单条记录] 或 [一批记录],及出现异常 Handler crashed with error <Ormer> table: `.` not found, make sure it was registered with `RegisterModel()`
    go json 序列号、反序列号和数据类型转换
    go json 转换忽略字段、控制字段可有可无
    Flutter 使用 flutter_inappbrowser 加载 H5 及与 js 交互,Methods marked with @UiThread must be executed on the main thread . Current thread: JavaBridge
  • 原文地址:https://www.cnblogs.com/InductiveSorting-QYF/p/13689720.html
Copyright © 2020-2023  润新知