• BZOJ4552:[TJOI2016&HEOI2016]排序(线段树,二分)


    Description

    在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他。
    这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序
    最后询问第q位置上的数字。

    Input

    输入数据的第一行为两个整数n和m。n表示序列的长度,m表示局部排序的次数。1 <= n, m <= 10^5第二行为n个整数,表示1到n的一个全排列。
    接下来输入m行,每一行有三个整数op, l, r, op为0代表升序排序,op为1代表降序排序, l, r 表示排序的区间。
    最后输入一个整数q,q表示排序完之后询问的位置, 1 <= q <= n。1 <= n <= 10^5,1 <= m <= 10^5

    Output

    输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第q位置上的数字。

    Sample Input

    6 3
    1 6 2 5 3 4
    0 1 4
    1 3 6
    0 2 4
    3

    Sample Output

    5

    Solution

    也就只有刷刷水才能挽救一下博客文章数量这样子

    二分最终的答案是不是小于等于$mid$,然后把小于等于$mid$的置为$0$,大于的置为$1$。

    然后区间$sort$就可以查询一下区间$1$的个数然后用线段树区间覆盖来搞。

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define N (100009)
     5 using namespace std;
     6 
     7 struct Edge{int val,down;}Segt[N<<2];
     8 int n,m,p,a[N],opt[N],l[N],r[N];
     9 
    10 void Pushdown(int now,int l,int r)
    11 {
    12     if (Segt[now].down!=-1)
    13     {
    14         int mid=(l+r)>>1;
    15         Segt[now<<1].down=Segt[now<<1|1].down=Segt[now].down;
    16         Segt[now<<1].val=(mid-l+1)*Segt[now].down;
    17         Segt[now<<1|1].val=(r-mid)*Segt[now].down;
    18         Segt[now].down=-1;
    19     }
    20 }
    21 
    22 void Update(int now,int l,int r,int l1,int r1,int k)
    23 {
    24     if (l>r1 || r<l1) return;
    25     if (l1<=l && r<=r1)
    26     {
    27         Segt[now].val=(r-l+1)*k;
    28         Segt[now].down=k;
    29         return;
    30     }
    31     Pushdown(now,l,r);
    32     int mid=(l+r)>>1;
    33     Update(now<<1,l,mid,l1,r1,k);
    34     Update(now<<1|1,mid+1,r,l1,r1,k);
    35     Segt[now].val=Segt[now<<1].val+Segt[now<<1|1].val;
    36 }
    37 
    38 int Query(int now,int l,int r,int l1,int r1)
    39 {
    40     if (l>r1 || r<l1) return 0;
    41     if (l1<=l && r<=r1) return Segt[now].val;
    42     Pushdown(now,l,r);
    43     int mid=(l+r)>>1;
    44     return Query(now<<1,l,mid,l1,r1)+Query(now<<1|1,mid+1,r,l1,r1);
    45 }
    46 
    47 bool check(int x)
    48 {
    49     for (int i=1; i<=n*4; ++i) Segt[i].val=0, Segt[i].down=-1;
    50     for (int i=1; i<=n; ++i)
    51         Update(1,1,n,i,i,a[i]>x);
    52     for (int i=1; i<=m; ++i)
    53     {
    54         int sum=Query(1,1,n,l[i],r[i]);
    55         if (opt[i]==0) Update(1,1,n,r[i]-sum+1,r[i],1), Update(1,1,n,l[i],r[i]-sum,0);
    56         else Update(1,1,n,l[i],l[i]+sum-1,1), Update(1,1,n,l[i]+sum,r[i],0);
    57     }
    58     return !Query(1,1,n,p,p);
    59 }
    60 
    61 int main()
    62 {
    63     scanf("%d%d",&n,&m);
    64     for (int i=1; i<=n; ++i)
    65         scanf("%d",&a[i]);
    66     for (int i=1; i<=m; ++i)
    67         scanf("%d%d%d",&opt[i],&l[i],&r[i]);
    68     scanf("%d",&p);
    69     int l=1,r=n,ans=-1;
    70     while (l<=r)
    71     {
    72         int mid=(l+r)>>1;
    73         if (check(mid)) r=mid-1,ans=mid;
    74         else l=mid+1;
    75     }
    76     printf("%d
    ",ans);
    77 }
  • 相关阅读:
    探索javascript----事件对象下的各种X和Y
    css2----兼容----ie67的3像素bug
    探索javascript----拖拽
    一、Rabbitmq安装与配置信息
    四、RABBITMQ特点
    一,activemq安装和配置相关信息
    三,activemq持久化消息到mysql数据库中
    三、RABBITMQ的几个基本概念
    二、JMS和AMQP的对比
    hibernate的工作原理
  • 原文地址:https://www.cnblogs.com/refun/p/10140119.html
Copyright © 2020-2023  润新知