求助分析时间复杂度 刚才比赛的B题
  • 板块学术版
  • 楼主AllureLove2410喜欢若彤
  • 当前回复9
  • 已保存回复9
  • 发布时间2023/1/14 18:19
  • 上次更新2023/10/24 04:15:42
查看原帖
求助分析时间复杂度 刚才比赛的B题
556455
AllureLove2410喜欢若彤楼主2023/1/14 18:19

70pts,T了后三个点

code:

#include<bits/stdc++.h>
using namespace std;
const int xrt=1e6+3;
int n,q;
int a[xrt];
int ans;
int b[xrt];
struct zsm{
	int l,r;
	int sum,lazy;
}t[xrt<<2];
void build(int x,int l,int r){
	t[x].l=l,t[x].r=r;
	if(l==r){
		if(a[l]!=0)t[x].sum=a[l];
		return;
	}
	int mid=l+((r-l)>>1);
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	t[x].sum=t[x<<1].sum+t[x<<1|1].sum;
	return;
}
void down(int x){
	if(t[x].lazy!=0){
		t[x<<1].sum+=(t[x<<1].r-t[x<<1].l+1)*t[x].lazy;
		t[x<<1|1].sum+=(t[x<<1|1].r-t[x<<1|1].l+1)*t[x].lazy;
		t[x<<1].lazy+=t[x].lazy;
		t[x<<1|1].lazy+=t[x].lazy;
		t[x].lazy=0;
	}
	return;
}
void fix(int x,int l,int r,int k){
	if(t[x].l>=l&&t[x].r<=r){
		t[x].sum+=(t[x].r-t[x].l+1)*k;
		t[x].lazy+=k;
		return;
	}
	down(x);
	int mid=t[x].l+((t[x].r-t[x].l)>>1);
	if(l<=mid){
		fix(x<<1,l,r,k);
	}
	if(r>mid){
		fix(x<<1|1,l,r,k);
	}
	t[x].sum=t[x<<1].sum+t[x<<1|1].sum;
	return;
}
int ask(int x,int l,int r){
	if(t[x].l>=l&&t[x].r<=r){
		return t[x].sum;
	}
	down(x);
	int mid=t[x].l+((t[x].r-t[x].l)>>1);
	int ans=0;
	if(l<=mid){
		ans+=ask(x<<1,l,r);
	}
	if(r>mid){
		ans+=ask(x<<1|1,l,r);
	}
	return ans;
}
void work1(int x){//删除x 找到x前面的第一个 和 x后面的第一个  
	int l=0,r=x;
	int id1=0;
	bool flag1=true,flag2=true;
	while(l<=r){
		int mid=l+((r-l)>>1);
//		cout<<mid<<"\n";
		if(ask(1,mid,r)!=0){
			//cout<<ask(1,mid,r)<<" "<<mid<<" "<<r<<"\n";
			l=mid+1;
			id1=mid;
		}else{
			r=mid-1;
		}
	}
	if(id1==0){
		l=x,r=1e6;	
		while(l<=r){
			int mid=l+((r-l)>>1);
			if(ask(1,mid,r)!=0){
				l=mid+1;
				id1=mid;
			}else{
				r=mid-1;
			}
		}
		flag1=false;
	}//cout<<id1<<" ";
	l=x+1,r=1e6;
	int id2=0;
	while(l<=r){
		int mid=l+((r-l)>>1);
//		cout<<mid<<"\n";
		if(ask(1,l,mid)!=0){
			r=mid-1;
			id2=mid;
		}else{
			l=mid+1;
		}
	}
	if(id2==0){
		l=0,r=x-1;
		while(l<=r){
			int mid=l+((r-l)>>1);
			if(ask(1,l,mid)!=0){
				r=mid-1;
				id2=mid;
			}else{
				l=mid+1;
			}
		}
		flag2=false;
	}
	if(flag1&&flag2){
		ans-=x-id1;
		ans-=id2-x;
		ans+=id2-id1;
	}
	if(flag1==false&&flag2==true){
		ans-=id1-x;
		ans-=id2-x;
		ans+=id1-id2;
	}
	if(flag1==true&&flag2==false){
		ans-=x-id1;
		ans-=x-id2;
		ans+=id1-id2;
	}
	cout<<ans<<"\n";
	return;
}
void work2(int x){//添加 x  找到x前面的第一个 和 x 后面的第一 个 
	int l=0,r=x;
	int id1=0;
	bool flag1=true,flag2=true;
	while(l<=r){
		int mid=l+((r-l)>>1);
		if(ask(1,mid,r)!=0){
			l=mid+1;
			id1=mid;
		}else{
			r=mid-1;
		}
	}
	if(id1==0){
		l=x,r=1e6;	
		while(l<=r){
			int mid=l+((r-l)>>1);
			if(ask(1,mid,r)!=0){
				l=mid+1;
				id1=mid;
			}else{
				r=mid-1;
			}
		}
		flag1=false;
	}
	l=x+1,r=1e6;
	int id2=0;
	while(l<=r){
		int mid=l+((r-l)>>1);
		if(ask(1,l,mid)!=0){
			r=mid-1;
			id2=mid;
		}else{
			l=mid+1;
		}
	}
	if(id2==0){
		l=0,r=x-1;
		while(l<=r){
			int mid=l+((r-l)>>1);
			if(ask(1,l,mid)!=0){
				r=mid-1;
				id2=mid;
			}else{
				l=mid+1;
			}
		}
		flag2=false;
	}
	if(flag1&&flag2){
		ans+=x-id1;
		ans+=id2-x;
		ans-=id2-id1;
	}else{
		if(flag1==false){
			ans+=id1-x;
			ans+=id2-x;
			ans-=id1-id2;
		}else{
			ans+=x-id1;
			ans+=x-id2;
			ans-=id1-id2;
		}
	}
	cout<<ans<<"\n";
	return; 
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
//	freopen("abs3.in","r",stdin);
//	freopen("abs3.ans","w",stdout);
	cin>>n>>q;
	for(int i=1,x;i<=n;i++){
		cin>>x;
		a[x]++;
		b[i]=x;
	}
	build(1,1,1000000);
	sort(b+1,b+n+1);
	for(int i=2;i<=n;i++){
		ans+=b[i]-b[i-1];
	}
	ans+=b[n]-b[1];
	while(q--){
		int opt,x;
		cin>>opt>>x;
		if(opt==1){
			if(a[x]==0){
				cout<<"-1\n";
				continue;
			}else{
				a[x]--;
				fix(1,x,x,-1);
				work1(x);
			}
		}else{
			work2(x);
			fix(1,x,x,1);
			a[x]++;
		}
	}
	return 0;
}
2023/1/14 18:19
加载中...