【BZOJ4552】排序(线段树,二分答案)

题面

BZOJ

题解

好神的题啊
直接排序我们做不到
怎么维护?
考虑一下,如果我们随便假设一个答案
怎么检验它是否成立?
把这个数设成\(1\),其他的数字都设成\(0\)
最后检查一下这个位置是不是\(1\)就好啦

但是这样没法排序
那么,我们考虑二分一个答案,
把所有比\(mid\)大的数都设成\(1\)
这样,如果在第\(Q\)位上的数字是\(1\)
意味着有一个不小于当前\(mid\)的数在这个位置上
否则就是一个比\(mid\)小的数在这个位置上
这样就可以二分答案啦

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 222222
#define lson (now<<1)
#define rson (now<<1|1)
inline int read()
{
    RG int x=0,t=1;RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
struct Work{int l,r,opt;}p[MAX];
int t[MAX<<2],tag[MAX<<2];
int a[MAX],b[MAX],n,m,Q;
void Build(int now,int l,int r)
{
    tag[now]=-1;
    if(l==r){t[now]=b[l];return;}
    int mid=(l+r)>>1;
    Build(lson,l,mid);Build(rson,mid+1,r);
    t[now]=t[lson]+t[rson];
}
void puttag(int now,int l,int r,int w)
{
    tag[now]=w;
    t[now]=(r-l+1)*w;
}
void pushdown(int now,int l,int r)
{
    if(tag[now]==-1)return;
    int mid=(l+r)>>1;
    puttag(lson,l,mid,tag[now]);
    puttag(rson,mid+1,r,tag[now]);
    tag[now]=-1;
}
int Query(int now,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)return t[now];
    pushdown(now,l,r);
    int ret=0,mid=(l+r)>>1;
    if(L<=mid)ret+=Query(lson,l,mid,L,R);
    if(R>mid)ret+=Query(rson,mid+1,r,L,R);
    return ret;
}
void Modify(int now,int l,int r,int L,int R,int w)
{
    if(L<=l&&r<=R){puttag(now,l,r,w);return;}
    pushdown(now,l,r);
    int mid=(l+r)>>1;
    if(L<=mid)Modify(lson,l,mid,L,R,w);
    if(R>mid)Modify(rson,mid+1,r,L,R,w);
    t[now]=t[lson]+t[rson];
}
void Work(int i)
{
    int ss=Query(1,1,n,p[i].l,p[i].r);
    if(p[i].opt==0)
    {
        ss=p[i].r-p[i].l+1-ss;
        if(ss!=0)Modify(1,1,n,p[i].l,p[i].l+ss-1,0);
        if(ss!=p[i].r-p[i].l+1)Modify(1,1,n,p[i].l+ss,p[i].r,1);
    }
    else
    {
        if(ss!=0)Modify(1,1,n,p[i].l,p[i].l+ss-1,1);
        if(ss!=p[i].r-p[i].l+1)Modify(1,1,n,p[i].l+ss,p[i].r,0);
    }
}
bool check(int mid)
{
    for(int i=1;i<=n;++i)if(a[i]>=mid)b[i]=1;else b[i]=0;
    Build(1,1,n);
    for(int i=1;i<=m;++i)Work(i);
    return Query(1,1,n,Q,Q);
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;++i)a[i]=read();
    for(int i=1;i<=m;++i)p[i].opt=read(),p[i].l=read(),p[i].r=read();
    Q=read();
    int l=1,r=n,ans=0;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(check(mid))l=mid+1,ans=mid;
        else r=mid-1;
    }
    printf("%d\n",ans);
    return 0;
}

【BZOJ4552】排序(线段树,二分答案)的更多相关文章

  1. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  2. Codeforces Gym 100803G Flipping Parentheses 线段树+二分

    Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...

  3. hdu4614 线段树+二分 插花

    Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...

  4. BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案)

    BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案) 题意 : 给你一个长为\(R\)宽为\(C\)的矩阵,第\(i\)行\(j\)列的数为\(P_{i,j}\). 有\(m\)次 ...

  5. 【BZOJ-2653】middle 可持久化线段树 + 二分

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1298  Solved: 734[Submit][Status][Discu ...

  6. poj City Horizon (线段树+二分离散)

    http://poj.org/problem?id=3277 City Horizon Time Limit: 2000MS   Memory Limit: 65536K Total Submissi ...

  7. hdu 3333 Turing Tree 图灵树(线段树 + 二分离散)

    http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Others)    ...

  8. 计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task

    E. A Simple Task Problem's Link: http://codeforces.com/problemset/problem/558/E Mean: 给定一个字符串,有q次操作, ...

  9. CodeForces 558E(计数排序+线段树优化)

    题意:一个长度为n的字符串(只包含26个小字母)有q次操作 对于每次操作 给一个区间 和k k为1把该区间的字符不降序排序 k为0把该区间的字符不升序排序 求q次操作后所得字符串 思路: 该题数据规模 ...

  10. noip 2012 借教室 (线段树 二分)

    /* 维护区间最小值 数据不超int 相反如果long long的话会有一组数据超时 无视掉 ll int */ #include<iostream> #include<cstdio ...

随机推荐

  1. [linux系统]--spawn 用法

    spawn与except组合可达到远程登录设备执行命令的作用 下面是登录设备的一段代码 #!/usr/bin/expect -f user=root host=1.1.1.1 password=roo ...

  2. Java并发包中CountDownLatch的工作原理、使用示例

    1. CountDownLatch的介绍 CountDownLatch是一个同步工具,它主要用线程执行之间的协作.CountDownLatch 的作用和 Thread.join() 方法类似,让一些线 ...

  3. acm常见算法及例题

    转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题  初期:一.基本算法:     (1)枚举. (poj17 ...

  4. 使用sphinx生成Python文档

    发现找不到matplotlib.sphinxext.mathmpl: 可以直接easy_install matplotlib,也可以去这里下载安装包 发现exception: matplotlib r ...

  5. MySQL忘记root用户密码修改方法

    一般来说在MySQL修改用户密码有好几种方法: 1.修改自己的密码可用: set password=password('123456'); 2.修改其它用户的密码可用: set password fo ...

  6. php中curl的详细解说

    cURL可以使用URL的语法模拟浏览器来传输数据, 因为它是模拟浏览器,因此它同样支持多种协议, FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE ...

  7. github pages 添加godaddy的dns解析

    转自: http://andrewsturges.com/blog/jekyll/tutorial/2014/11/06/github-and-godaddy.html I own a custom ...

  8. grads 用arcgis分析站点的网格

    第一步,用工具创建渔网(要素类) 第二步:将站点excel导入,生成点要素 站点excle,点击上面节点导出数据即可. 第三步,叠加在一起,找网格编号.

  9. 迷你sql profile,给缺少sql跟踪的朋友们

    如果你的数据库没有sqlprofile,看这里. 如果你没时间装sqlserver那一系列的东西,看看这里,也许能解决呢. 这是一个迷你版的sqlprofile ,在win7下测试,链接sqlserv ...

  10. CollectionFramework