题意:给定一个n个数的排列,有m次操作:op,l,r
op=0时表示将位置【L,R】升序排序
op=1时表示将位置【L,R】降序排序
最后询问第q个位置上的数字
n,m,q<=1e5
思路:From https://blog.csdn.net/stone41123/article/details/84672207
二分转化为判定问题之后线段树需要实现区间覆盖和询问区间和
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef long double ld; 7 typedef pair<int,int> PII; 8 typedef pair<ll,ll> Pll; 9 typedef vector<int> VI; 10 typedef vector<PII> VII; 11 typedef pair<ll,ll>P; 12 #define N 200010 13 #define M 6000010 14 #define INF 1e9 15 #define fi first 16 #define se second 17 #define MP make_pair 18 #define pb push_back 19 #define pi acos(-1) 20 #define mem(a,b) memset(a,b,sizeof(a)) 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 23 #define lowbit(x) x&(-x) 24 #define Rand (rand()*(1<<16)+rand()) 25 #define id(x) ((x)<=B?(x):m-n/(x)+1) 26 #define ls p<<1 27 #define rs p<<1|1 28 #define fors(i) for(auto i:e[x]) if(i!=p) 29 30 const int MOD=1e8+7,inv2=(MOD+1)/2; 31 int p=1e4+7; 32 double eps=1e-8; 33 int dx[4]={-1,1,0,0}; 34 int dy[4]={0,0,-1,1}; 35 36 int read() 37 { 38 int v=0,f=1; 39 char c=getchar(); 40 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 41 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 42 return v*f; 43 } 44 45 ll readll() 46 { 47 ll v=0,f=1; 48 char c=getchar(); 49 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 50 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 51 return v*f; 52 } 53 54 struct Q 55 { 56 int l,r,op; 57 }a[N]; 58 59 struct node 60 { 61 int s,tag; 62 }t[N<<2]; 63 64 int b[N]; 65 66 void pushup(int p) 67 { 68 t[p].s=t[ls].s+t[rs].s; 69 } 70 71 void pushdown(int l,int r,int p) 72 { 73 if(t[p].tag!=-1) 74 { 75 int mid=(l+r)>>1; 76 t[ls].s=t[p].tag*(mid-l+1); 77 t[rs].s=t[p].tag*(r-mid); 78 t[ls].tag=t[rs].tag=t[p].tag; 79 t[p].tag=-1; 80 } 81 } 82 83 void build(int l,int r,int p,int x) 84 { 85 t[p].tag=-1; 86 if(l==r) 87 { 88 if(b[l]<=x) t[p].s=0; 89 else t[p].s=1; 90 return; 91 } 92 int mid=(l+r)>>1; 93 build(l,mid,ls,x); 94 build(mid+1,r,rs,x); 95 pushup(p); 96 } 97 98 void update(int l,int r,int x,int y,int v,int p) 99 { 100 if(x<=l&&r<=y) 101 { 102 t[p].s=v*(r-l+1); 103 t[p].tag=v; 104 return; 105 } 106 pushdown(l,r,p); 107 int mid=(l+r)>>1; 108 if(x<=mid) update(l,mid,x,y,v,ls); 109 if(y>mid) update(mid+1,r,x,y,v,rs); 110 pushup(p); 111 } 112 113 int query(int l,int r,int x,int y,int p) 114 { 115 if(x<=l&&r<=y) return t[p].s; 116 pushdown(l,r,p); 117 int mid=(l+r)>>1; 118 int res=0; 119 if(x<=mid) res+=query(l,mid,x,y,ls); 120 if(y>mid) res+=query(mid+1,r,x,y,rs); 121 return res; 122 } 123 124 int main() 125 { 126 //freopen("1.in","r",stdin); 127 //freopen("1.out","w",stdout); 128 int n=read(),m=read(); 129 rep(i,1,n) b[i]=read(); 130 rep(i,1,m) a[i].op=read(),a[i].l=read(),a[i].r=read(); 131 int q=read(); 132 int l=0,r=n,ans=0; 133 while(l<=r) 134 { 135 int mid=(l+r)>>1; 136 build(1,n,1,mid); 137 rep(i,1,m) 138 { 139 int num=query(1,n,a[i].l,a[i].r,1); 140 if(!a[i].op) 141 { 142 if(num) update(1,n,a[i].r-num+1,a[i].r,1,1); 143 if(a[i].l<=a[i].r-num) update(1,n,a[i].l,a[i].r-num,0,1); 144 } 145 else 146 { 147 if(num) update(1,n,a[i].l,a[i].l+num-1,1,1); 148 if(a[i].l+num<=a[i].r) update(1,n,a[i].l+num,a[i].r,0,1); 149 } 150 } 151 if(query(1,n,q,q,1)) l=mid+1; 152 else ans=mid,r=mid-1; 153 } 154 printf("%d ",ans); 155 return 0; 156 }