BC#76原题……
二分答案,把小于等于mid的设成零,大于mid的设成1,然后排序可视为区间赋值和区间求和,可用线段树做
当mid大于等于答案的时候,最后p的位置一定是0,当mid小于答案的时候,p的位置一定是1,所以满足可二分性
复杂度O(n log^2 n)
#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define MAXN 100010 #define MAXM 1010 #define ll long long #define INF 1000000000 #define MOD 1000000007 #define eps 1e-8 int n,m; int a[MAXN]; bool c[MAXN]; int L[MAXN],R[MAXN]; int s[MAXN*4],ch[MAXN*4]; int p; inline void ud(int x){ s[x]=s[x<<1]+s[x<<1|1]; } inline void toch(int x,int y,int z,int cv){ ch[x]=cv; s[x]=(z-y+1)*cv; } inline void pd(int x,int y,int z){ if(ch[x]!=-1){ int mid=y+z>>1; toch(x<<1,y,mid,ch[x]); toch(x<<1|1,mid+1,z,ch[x]); ch[x]=-1; } } void build(int x,int y,int z,int l){ ch[x]=-1; if(y==z){ if(a[y]<=l){ s[x]=0; }else{ s[x]=1; } return ; } int mid=y+z>>1; build(x<<1,y,mid,l); build(x<<1|1,mid+1,z,l); ud(x); } int ask(int x,int y,int z,int l,int r){ if(y==l&&z==r){ return s[x]; } pd(x,y,z); int mid=y+z>>1; if(r<=mid){ return ask(x<<1,y,mid,l,r); }else if(l>mid){ return ask(x<<1|1,mid+1,z,l,r); }else{ return ask(x<<1,y,mid,l,mid)+ask(x<<1|1,mid+1,z,mid+1,r); } } void change(int x,int y,int z,int l,int r,int cv){ if(l>r){ return ; } if(y==l&&z==r){ toch(x,y,z,cv); return ; } pd(x,y,z); int mid=y+z>>1; if(r<=mid){ change(x<<1,y,mid,l,r,cv); }else if(l>mid){ change(x<<1|1,mid+1,z,l,r,cv); }else{ change(x<<1,y,mid,l,mid,cv); change(x<<1|1,mid+1,z,mid+1,r,cv); } ud(x); } bool OK(int x){ int i; build(1,1,n,x); for(i=1;i<=m;i++){ int t=ask(1,1,n,L[i],R[i]); if(!c[i]){ change(1,1,n,L[i],R[i]-t,0); change(1,1,n,R[i]-t+1,R[i],1); }else{ change(1,1,n,L[i],L[i]+t-1,1); change(1,1,n,L[i]+t,R[i],0); } } return !ask(1,1,n,p,p); } int main(){ int i; scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ scanf("%d",&a[i]); } for(i=1;i<=m;i++){ scanf("%d%d%d",&c[i],&L[i],&R[i]); } scanf("%d",&p); int l=1,r=n; int ans; while(l<=r){ int mid=l+r>>1; if(OK(mid)){ ans=mid; r=mid-1; }else{ l=mid+1; } } printf("%d\n",ans); return 0; } /* 6 3 1 6 2 5 3 4 0 1 4 1 3 6 0 2 4 3 */