MLE求助
查看原帖
MLE求助
289230
ricky0916楼主2023/12/30 12:03

这段代码看上去怎么也不会MLE吧。

#include<bits/stdc++.h>
using namespace std;
long long ans;
int n,k,aa,bb,tot,ott,xxx[300010];
struct qj{
	int xx,yy;
}q[300010];
bool cmp(qj a,qj b){
	return a.xx+a.yy<b.xx+b.yy;
}
struct edge{
	int le,ri,num1,num2;
	long long sum1,sum2;
}val[3000010];
int init_val[300010],totin;
void push_up(int rt){
	val[rt].num1=val[rt<<1].num1+val[rt<<1|1].num1;
	val[rt].num2=val[rt<<1].num2+val[rt<<1|1].num2;
	val[rt].sum1=val[rt<<1].sum1+val[rt<<1|1].sum1;
	val[rt].sum2=val[rt<<1].sum2+val[rt<<1|1].sum2;
}
void build(int rt,int l,int r){
	if(l==r){
		val[rt].le=val[rt].ri=init_val[l];
		return;
	}
	int mid=(l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	val[rt].le=val[rt<<1].le;
	val[rt].ri=val[rt<<1|1].ri;
}
void update_one(int op,int rt,int l,int r,int xx,int add){
	if(l==r){
		if(op==1) val[rt].num1+=add,val[rt].sum1+=add*val[rt].le;
		else val[rt].num2+=add,val[rt].sum2+=add*val[rt].le;
		return;
	}
	int mid=(l+r)>>1;
	if(val[rt<<1].le<=xx&&val[rt<<1].ri>=xx) update_one(op,rt<<1,l,mid,xx,add);
	else update_one(op,rt<<1|1,mid+1,r,xx,add);
	push_up(rt);
}
void insert(int op,int xx){
	update_one(op,1,1,totin,xx,1);
}
void del(int op,int xx){
	update_one(op,1,1,totin,xx,-1);
}
int query_number(int op,int rt,int l,int r,int xx){
	if(xx==0) return val[rt].le;
	//printf("%d %d %d %d %d %d %d\n",val[rt].le,val[rt].ri,val[rt].num2,val[rt<<1].num2,val[rt<<1|1].num2,l,r);
	if(l==r) return val[rt].ri|val[rt].le;
	int mid=(l+r)>>1;
	if(op==1){
		if(val[rt<<1].num1>xx){
			return query_number(op,rt<<1,l,mid,xx);
		}
		else{
			return query_number(op,rt<<1|1,mid+1,r,xx-val[rt<<1].num1);	
		}
	}
	else{
		if(val[rt<<1].num2>xx){
			return query_number(op,rt<<1,l,mid,xx);
		}
		else{
			return query_number(op,rt<<1|1,mid+1,r,xx-val[rt<<1].num2);	
		}
	}
}
long long calc(int op,int rt,int l,int r,int xx){
	if(l==r) return 0;
	int mid=(l+r)>>1;
	if(op==1){
		if(val[rt<<1].ri<xx) return 1ll*xx*val[rt<<1].num1-val[rt<<1].sum1+calc(op,rt<<1|1,mid+1,r,xx);
		else return calc(op,rt<<1,l,mid,xx)+val[rt<<1|1].sum1-1ll*xx*val[rt<<1|1].num1;
	}
	else{
		if(val[rt<<1].ri<xx) return 1ll*xx*val[rt<<1].num2-val[rt<<1].sum2+calc(op,rt<<1|1,mid+1,r,xx);
		else return calc(op,rt<<1,l,mid,xx)+val[rt<<1|1].sum2-1ll*xx*val[rt<<1|1].num2;
	}
}
char op[20][10];
int main(){
	scanf("%d%d",&k,&n);
	for(int i=1;i<=n;i++){
		scanf("%s%d%s%d",op[0],&aa,op[1],&bb);
		if(op[0][0]==op[1][0]) ans+=abs(aa-bb);
		else{
			++ans;
			if(aa>bb) swap(aa,bb);
			q[++tot]=(qj){aa,bb};
			xxx[++ott]=aa;
			xxx[++ott]=bb;
		}
	}
	if(k==1){
		sort(xxx+1,xxx+ott+1);
		int di=xxx[ott/2];
		for(int i=1;i<=ott;i++) ans+=abs(xxx[i]-di);
	}
	else{
		
		sort(q+1,q+tot+1,cmp);
		sort(xxx+1,xxx+ott+1);
		init_val[0]=1e9+7;
		for(int i=1;i<=ott;i++){
			if(init_val[totin]!=xxx[i]) init_val[++totin]=xxx[i];
		}
		build(1,1,totin);
		for(int i=1;i<=tot;i++) insert(2,q[i].xx),insert(2,q[i].yy);
		long long aaa=1e18;
		for(int i=1;i<=tot;i++){
			int zws1=query_number(1,1,1,totin,(i-1)),zws2=query_number(2,1,1,totin,(tot-i+1));
			//printf("%d %d\n",zws1,zws2);
			aaa=min(aaa,calc(1,1,1,totin,zws1)+calc(2,1,1,totin,zws2));
			del(2,q[i].xx);
			del(2,q[i].yy);
			insert(1,q[i].xx);
			insert(1,q[i].yy);
		}
		int zws1=query_number(1,1,1,totin,tot),zws2=query_number(2,1,1,totin,0);
		aaa=min(aaa,calc(1,1,1,totin,zws1)+calc(2,1,1,totin,zws2));
		ans+=aaa;
	}
	printf("%lld",ans);
	return 0;
}
2023/12/30 12:03
加载中...