在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题
,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排
序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q
位置上的数字。
标签:直接 个数 problems 二分 ++ div lan name font
输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第q位置上的数字。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<vector> 7 #include<queue> 8 const int N=1e5+10; 9 using namespace std; 10 int mid,sum1,q; 11 int n,m; 12 int a[N]; 13 struct node{ 14 int l,r,opt; 15 }ask[N]; 16 struct NODE{ 17 int l,r,val,f; 18 }tr[N<<2]; 19 void build(int p,int l,int r){//cout<<"B"<<endl; 20 tr[p].l=l,tr[p].r=r; 21 if(l==r){//cout<<"break"<<endl; 22 tr[p].f=-1; 23 tr[p].val=(a[l]>=mid); 24 return ; 25 } 26 tr[p].f=-1; 27 int mid=(l+r)>>1; 28 build(p<<1,l,mid); 29 build(p<<1|1,mid+1,r); 30 tr[p].val=tr[p<<1].val+tr[p<<1|1].val; 31 } 32 void down(int p){ 33 if(tr[p].f<0) return ; 34 tr[p<<1].f=tr[p].f; 35 tr[p<<1|1].f=tr[p].f;//lanbiaojizhijiefugai 36 tr[p<<1].val=(tr[p<<1].r-tr[p<<1].l+1)*tr[p].f; 37 tr[p<<1|1].val=(tr[p<<1|1].r-tr[p<<1|1].l+1)*tr[p].f; 38 tr[p].f=-1; 39 } 40 void change(int p,int l,int r,int val){ 41 if(l<=tr[p].l&&tr[p].r<=r){ 42 tr[p].f=val; 43 tr[p].val=(tr[p].r-tr[p].l+1)*val;//zhijiefuzhi// 44 return ; 45 } 46 if(l>tr[p].r||r<tr[p].l) return ; 47 down(p); 48 int mid=(tr[p].l+tr[p].r)>>1; 49 if(l<=mid) change(p<<1,l,r,val); 50 if(r>mid) change(p<<1|1,l,r,val); 51 tr[p].val=tr[p<<1].val+tr[p<<1|1].val; 52 } 53 void query(int p,int l,int r){//cout<<p<<" "<<l<<" "<<r<<endl; 54 if(l<=tr[p].l&&tr[p].r<=r){//cout<<"break"<<endl; 55 sum1+=tr[p].val;// 56 return ; 57 } 58 if(l>tr[p].r||r<tr[p].l) return ;//特判 59 down(p); 60 int mid=(tr[p].l+tr[p].r)>>1; 61 if(l<=mid)query(p<<1,l,r); 62 if(r>mid)query(p<<1|1,l,r); 63 } 64 bool check(int x){ 65 build(1,1,n); 66 for(int i=1;i<=m;i++){ 67 sum1=0;query(1,ask[i].l,ask[i].r); 68 if(ask[i].opt==0){//升序 69 //cout<<"Q"<<endl; 70 change(1,ask[i].l,ask[i].r-sum1,0);// 71 change(1,ask[i].r-sum1+1,ask[i].r,1);// 72 } 73 else{ 74 //cout<<"Q"<<endl; 75 change(1,ask[i].l+sum1,ask[i].r,0); 76 change(1,ask[i].l,ask[i].l+sum1-1,1); 77 } 78 } 79 //for(int i=1;i<=n;i++) cout<<tr[i].val<<" "; 80 sum1=0; 81 query(1,q,q); 82 //cout<<sum1<<endl; 83 if(sum1) return true; 84 else return false; 85 } 86 int main(){ 87 //freopen("sort9.in","r",stdin); 88 scanf("%d%d",&n,&m); 89 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 90 for(int i=1;i<=m;i++){ 91 scanf("%d%d%d",&ask[i].opt,&ask[i].l,&ask[i].r); 92 } 93 scanf("%d",&q); 94 int l=1,r=n,ans; 95 while(l<r){//cout<<"K"<<endl; 96 mid=(l+r)>>1;//cout<<l<<" "<<r<<" "<<mid<<endl; 97 //cout<<check(mid)<<endl; 98 if(check(mid)) ans=mid/*?*/,l=mid+1; 99 else r=mid; 100 } 101 printf("%d",ans); 102 }
标签:直接 个数 problems 二分 ++ div lan name font
原文地址:https://www.cnblogs.com/leom10/p/11272836.html