代码自测同标程,全T/M,求大佬指点迷津
查看原帖
代码自测同标程,全T/M,求大佬指点迷津
992529
upto_300楼主2024/11/23 10:46

用了离线01线段树+二分的做法

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,q,a[100005],ty[100005],l[100005],r[100005],ans;
struct O{
    int l,r,sum,lazy;
    int len(){return r-l+1;}
}o[400005];
void build(int it,int l,int r,int std){
    o[it].l=l,o[it].r=r,o[it].lazy=0;
    if(l==r){
        o[it].sum=a[l]>=std;
        return;
    }
    int mid=l+r>>1;
    build(it<<1,l,mid,std);
    build(it<<1|1,mid+1,r,std);
    o[it].sum=o[it<<1].sum+o[it<<1|1].sum;
}
void push(int it){
	if(o[it].lazy==0)return;
    if(o[it].lazy==1)
        o[it<<1].sum=o[it<<1].len(),
        o[it<<1|1].sum=o[it<<1|1].len();
    else
        o[it<<1].sum=o[it<<1|1].sum=0;
    o[it<<1].lazy=o[it<<1|1].lazy=o[it].lazy;
    o[it].lazy=0;
}
void update(int it,int l,int r,int x){
    if(o[it].l==l&&o[it].r==r){
        o[it].sum=x*o[it].len();
        o[it].lazy=(x==1?1:-1);
        return;
    }
    push(it);
    int mid=o[it].l+o[it].r>>1;
    if(mid>=r)update(it<<1,l,r,x);
    else if(mid<l)update(it<<1|1,l,r,x);
    else update(it<<1,l,mid,x),update(it<<1|1,mid+1,r,x);
    o[it].sum=o[it<<1].sum+o[it<<1|1].sum;
}
int query(int it,int l,int r){
    if(o[it].l==l&&o[it].r==r)return o[it].sum;
    push(it);
    int mid=o[it].l+o[it].r>>1;
    if(mid>=r)return query(it<<1,l,r);
    else if(mid<l)return query(it<<1|1,l,r);
    else return query(it<<1,l,mid)+query(it<<1|1,mid+1,r);
}
int query2(int it,int to){
    if(o[it].l==to&&o[it].r==to)return o[it].sum;
    push(it);
    int mid=o[it].l+o[it].r>>1;
    if(to<=mid)query2(it<<1,to);
    else query2(it<<1|1,to);
}
bool check(int std){
    build(1,1,n,std);
    for(int i=1;i<=m;i++){
        int cnt=query(1,l[i],r[i]);
		if(cnt==0||cnt==r[i]-l[i]+1)continue;
        else if(ty[i]==0){
            update(1,l[i],r[i]-cnt,0);
            update(1,r[i]-cnt+1,r[i],1);
        }else{
            update(1,l[i],l[i]+cnt-1,1);
            update(1,l[i]+cnt,r[i],0);
        }
    }
	return query2(1,q);
}
signed main(){
	freopen("in","r",stdin);
    cin>>n>>m;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=m;i++)scanf("%d%d%d",&ty[i],&l[i],&r[i]);
    cin>>q;
    int L=1,R=n;
    while(L<=R){
        int mid=L+R>>1,tf=check(mid);
		if(tf==1)
            L=mid+1,ans=mid;
        else R=mid-1;
    }
    cout<<ans;
}
2024/11/23 10:46
加载中...