Title Description
Input Format
Output Format
Sample
answer:
The very idea of god
That question if you really go sorted died. . .
But we still have to use to segment tree
But this road and tree kruscal the same fantastic ideas
We count on the q-half position
Every half, maintaining a segment tree,
We set up the current number is assigned to x, then we let all the leaf nodes greater than or equal to x 1, x is less than 0
We have a few maintenance interval 1,
If we put before ascending order into a period of violence, after a period of change 0, descending turn,
We query q What is the position of number
If it is 1, then the current dichotomy of x may be small, but it may be the answer, use the mid updated ans, because we are to make greater than equal to the node x is 1,
If it is 0, then the current x is too large, the smaller number should be consulted
Every half of all such checks again, the end of the half ans is the answer
Anti routine questions, a lot of accumulation
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<vector> #include<queue> #define int long long #define MAXN 100005 using namespace std; int n,m,a[MAXN],q,l,r,ans; struct node{ int opt,l,r; }ask[MAXN]; struct Segtree{ int l,r,val,laz; }tree[MAXN<<2]; void down(int k){ if(tree[k].laz==-1) return ; tree[k<<1].laz=tree[k].laz; tree[k<<1|1].laz=tree[k].laz; tree[k<<1].val=(tree[k<<1].r-tree[k<<1].l+1)*tree[k].laz; tree[k<<1|1].val=(tree[k<<1|1].r-tree[k<<1|1].l+1)*tree[k].laz; tree[k].laz=-1; } void build(int k,int l,int r,int x){ tree[k].l=l,tree[k].r=r; tree[k].laz=-1; if(l==r){ if(a[l]>=x) tree[k].val=1; else tree[k].val=0; return ; } int mid=(l+r)>>1; build(k<<1,l,mid,x); build(k<<1|1,mid+1,r,x); tree[k].val=tree[k<<1].val+tree[k<<1|1].val; } int query(int k,int opl,int opr){ int l=tree[k].l,r=tree[k].r; if(opl<=l&&r<=opr){ return tree[k].val; } down(k); int mid=(l+r)>>1; if(opr<=mid) return query(k<<1,opl,opr); if(opl>mid) return query(k<<1|1,opl,opr); return query(k<<1,opl,mid)+query(k<<1|1,mid+1,opr); } void change(int k,int opl,int opr,int val){ int l=tree[k].l,r=tree[k].r; if(opl<=l&&r<=opr){ tree[k].val=(r-l+1)*val; tree[k].laz=val; return ; } down(k); int mid=(l+r)>>1; if(opr<=mid) change(k<<1,opl,opr,val); else if(opl>mid) change(k<<1|1,opl,opr,val); else{ change(k<<1,opl,opr,val); change(k<<1|1,opl,opr,val); } tree[k].val=tree[k<<1].val+tree[k<<1|1].val; } bool check(int x){ build(1,1,n,x); for(int i=1;i<=m;i++){ int sum=query(1,ask[i].l,ask[i].r); if(sum==0||sum==ask[i].r-ask[i].l+1) continue; if(!ask[i].opt){ change(1,ask[i].l,ask[i].r-sum,0); change(1,ask[i].r-sum+1,ask[i].r,1); }else{ change(1,ask[i].l,ask[i].l+sum-1,1); change(1,ask[i].l+sum,ask[i].r,0); } } return query(1,q,q); } signed main(){ scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=1;i<=m;i++){ scanf("%lld%lld%lld",&ask[i].opt,&ask[i].l,&ask[i].r); } scanf("%lld",&q); l=1,r=n; while(l<=r){ int mid=(l+r)>>1; if(check(mid)) ans=mid,l=mid+1; else r=mid-1; } printf("%lld\n",ans); return 0; }