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

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

 #include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=,M=;
int n,m,q,a[N];
struct Modify {
bool type;
int l,r;
};
Modify o[M];
class SegmentTree {
#define _left <<1
#define _right <<1|1
private:
int val[N<<],tag[N<<];
void push_up(const int &p) {
val[p]=val[p _left]+val[p _right];
}
void push_down(const int &p,const int &b,const int &e) {
if(tag[p]==-) return;
const int mid=(b+e)>>;
tag[p _left]=tag[p _right]=tag[p];
val[p _left]=tag[p]*length(b,mid);
val[p _right]=tag[p]*length(mid+,e);
tag[p]=-;
}
int length(const int &b,const int &e) const {
return e-b+;
}
public:
void build(const int &p,const int &b,const int &e,const int &k) {
if(b==e) {
val[p]=a[b]>=k;
return;
}
tag[p]=-;
const int mid=(b+e)>>;
build(p _left,b,mid,k);
build(p _right,mid+,e,k);
push_up(p);
}
void modify(const int &p,const int &b,const int &e,const int &l,const int &r,const bool &x) {
if(b==l&&e==r) {
tag[p]=x;
val[p]=x*length(b,e);
return;
}
push_down(p,b,e);
const int mid=(b+e)>>;
if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),x);
if(r>mid) modify(p _right,mid+,e,std::max(mid+,l),r,x);
push_up(p);
}
int query(const int &p,const int &b,const int &e,const int &l,const int &r) {
if(b==l&&e==r) return val[p];
push_down(p,b,e);
const int mid=(b+e)>>;
int ret=;
if(l<=mid) ret+=query(p _left,b,mid,l,std::min(mid,r));
if(r>mid) ret+=query(p _right,mid+,e,std::max(mid+,l),r);
return ret;
}
#undef _left
#undef _right
};
SegmentTree t;
inline bool check(const int &k) {
t.build(,,n,k);
for(register int i=;i<m;i++) {
const int opt=o[i].type,l=o[i].l,r=o[i].r,cnt1=t.query(,,n,l,r),cnt0=r-l+-cnt1;
if(opt==) {
if(cnt0) t.modify(,,n,l,l+cnt0-,);
t.modify(,,n,l+cnt0,r,);
}
if(opt==) {
if(cnt1) t.modify(,,n,l,l+cnt1-,);
t.modify(,,n,l+cnt1,r,);
}
}
return t.query(,,n,q,q);
}
int main() {
n=getint(),m=getint();
for(register int i=;i<=n;i++) a[i]=getint();
for(register int i=;i<m;i++) {
const int opt=getint(),l=getint(),r=getint();
o[i]=(Modify){opt,l,r};
}
q=getint();
int l=,r=n;
while(l<=r) {
const int mid=(l+r)>>;
if(check(mid)) {
l=mid+;
} else {
r=mid-;
}
}
printf("%d\n",l-);
return ;
}

最新文章

  1. 22-React JSX语法
  2. IOS开发UI基础UIImagePickerController的属性
  3. android ExpandableListActivity的使用
  4. 概率图形模型(PGM)学习笔记(一)动机和概述
  5. 5天2亿活跃用户,QQ“LBS+AR”天降红包活动后台揭密
  6. 12_Python的(匿名函数)Lambda表达式_Python编程之路
  7. appniu踩坑
  8. Unreal 4 error 记录
  9. 【Python3爬虫】下载酷狗音乐上的歌曲
  10. 【Linux】SSH证书免密码远程登陆Linux(Putty)
  11. pinpoint初始化hbase脚本报错
  12. mysql5.7.20 windows 解压缩版安装
  13. Delphi全局热键的注册
  14. 二、Windows下TortoiseGit的安装与配置
  15. 微信h5支付源码DEMO参考
  16. Firefox浏览器【书签工具栏】里的网址链接无法删除的解决办法
  17. DIY简单功能的torrentkitty种子爬虫
  18. 在虚拟机上安装linux系统
  19. 使用命令行操控VirtualBox虚拟机
  20. Linux下Apache与httpd的区别与关系

热门文章

  1. RF,GBDT,XGBoost,lightGBM的对比
  2. SPFA - Luogu 3385 【模板】负环
  3. jmeter连接数据库之增删改查
  4. python - 接口自动化测试 - basic_data - 基础数据参数化方法封装
  5. Postgres 将查询结果同时插入数据表
  6. 直接插入排序(java实现)
  7. 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp
  8. 节点流——FileInputStream&amp;FileOutputStream
  9. POJ 1222 EXTENDED LIGHTS OUT(高斯消元解异或方程组)
  10. [国家集训队][bzoj 2152] 聪聪可可 [点分治]