luogu_P2824 [HEOI2016/TJOI2016]排序
https://www.luogu.org/problem/P2824
题目描述
在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q位置上的数字。
输入格式
输入数据的第一行为两个整数n和m。n表示序列的长度,m表示局部排序的次数。第二行为n个整数,表示1到n的一个全排列。接下来输入m行,每一行有三个整数op, l, r, op为0代表升序排序,op为1代表降序排序, l, r 表示排序的区间。最后输入一个整数q,q表示排序完之后询问的位置
输出格式
输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第q位置上的数字。
输入输出样例
输入 #1
6 3 1 6 2 5 3 4 0 1 4 1 3 6 0 2 4 3
输出 #1
5
说明/提示
河北省选2016第一天第二题。
对于30%的数据,n,m\leq 1000n,m≤1000
对于100%的数据,n,m\leq 10^5n,m≤105且始终1\leq q\leq n1≤q≤n
二分
#include<iostream> #include<cstdio> #define ri register int #define u long long namespace opt { inline u in() { u x(0),f(1); char s(getchar()); while(s<'0'||s>'9') { if(s=='-') f=-1; s=getchar(); } while(s>='0'&&s<='9') { x=(x<<1)+(x<<3)+s-'0'; s=getchar(); } return x*f; } } using opt::in; #define NN 100005 #define MM 100005 namespace xds { struct node { u l,r,sum,add; } a[NN<<2]; u b[NN]; void build(const u &rt,const u &l,const u &r) { a[rt].l=l,a[rt].r=r,a[rt].add=-1; if(l==r) { a[rt].sum=b[l]; return; } u mid(l+r>>1),_x(rt<<1),_y(rt<<1|1); build(_x,l,mid); build(_y,mid+1,r); a[rt].sum=a[_x].sum+a[_y].sum; } void pushdown(const u &rt) { if(a[rt].add!=-1) { u _x(rt<<1),_y(rt<<1|1); a[_x].sum=(a[_x].r-a[_x].l+1)*a[rt].add; a[_y].sum=(a[_y].r-a[_y].l+1)*a[rt].add; a[_x].add=a[rt].add,a[_y].add=a[rt].add; a[rt].add=-1; } } void update(const u &rt,const u &l,const u &r,const u &x) { if(a[rt].l>=l&&a[rt].r<=r) { a[rt].sum=(a[rt].r-a[rt].l+1)*x; a[rt].add=x; return; } pushdown(rt); u _x(rt<<1),_y(rt<<1|1); if(l<=a[_x].r) update(_x,l,r,x); if(r>=a[_y].l) update(_y,l,r,x); a[rt].sum=a[_x].sum+a[_y].sum; } u query(const u &rt,const u &l,const u &r) { if(a[rt].l>=l&&a[rt].r<=r) return a[rt].sum; pushdown(rt); u _x(rt<<1),_y(rt<<1|1),_re(0); if(l<=a[_x].r) _re+=query(_x,l,r); if(r>=a[_y].l) _re+=query(_y,l,r); return _re; } } namespace mainstay { struct node { u k,l,r; } a[MM]; u N,M,K,c[NN]; u check(const u &x) { for(ri i(1); i<=N; ++i) xds::b[i]=c[i]<=x; xds::build(1,1,N); for(ri i(1); i<=M; ++i) { u _t(xds::query(1,a[i].l,a[i].r)); if(!_t||_t==a[i].r-a[i].l+1) continue; if(a[i].k) { xds::update(1,a[i].r-_t+1,a[i].r,1); xds::update(1,a[i].l,a[i].r-_t,0); } else { xds::update(1,a[i].l,a[i].l+_t-1,1); xds::update(1,a[i].l+_t,a[i].r,0); } } return xds::query(1,K,K); } inline void solve() { N=in(),M=in(); for(ri i(1); i<=N; ++i) c[i]=in(); for(ri i(1); i<=M; ++i) a[i].k=in(),a[i].l=in(),a[i].r=in(); K=in(); u _l(1),_r(N),ans; while(_l<=_r) { u mid(_l+_r>>1); if(check(mid)) _r=mid-1,ans=mid; else _l=mid+1; } std::cout<<ans; } } int main() { //freopen("x.txt","r",stdin); std::ios::sync_with_stdio(false); mainstay::solve(); }