没过大样例0pts,求助
查看原帖
没过大样例0pts,求助
508558
Cybrex楼主2024/11/9 14:20
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
//定义部分
struct thing{
	int a,b;
};
thing w[N];
bool cp(thing x,thing y){
	if(x.a==y.a){
		return x.b>y.b;
	}
	return x.a>y.a;
}
struct quan{
	int w,v;
};
quan q[N];
bool cmp(quan x,quan y){
	if(x.w==y.w){
		return x.v>y.v;
	}
	return x.w>y.w;
}
//平衡树

struct node{
	int ls,rs,rd,sz,x,id;
};
node tr[N];
int rt=0,cnt=0;
void up(int u){
	tr[u].sz=tr[tr[u].ls].sz+tr[tr[u].rs].sz+1;
}
int nt(int x,int id){
	cnt++;
	tr[cnt]={0,0,rand(),1,x,id};
	return cnt;
}
void spt(int u,int &x,int &y,int key){
	if(!u){
		x=y=0;
		return;
	}
	if(tr[u].x<=key){
		x=u;
		spt(tr[u].rs,tr[u].rs,y,key);
	}
	else{
		y=u;
		spt(tr[u].ls,x,tr[u].ls,key);
	}
	up(u);
}
int mg(int u,int v){
	if(!u||!v){
		return u+v;
	}
	if(tr[u].rd>tr[v].rd){
		tr[u].rs=mg(tr[u].rs,v);
		up(u);
		return u;
	}
	else{
		tr[v].ls=mg(u,tr[v].ls);
		up(v);
		return v;
	}
}
void ins(int x,int id){
	int l,r;
	spt(rt,l,r,x);
	rt=mg(l,mg(nt(x,id),r));
}
void del(int x){
	int l,r,ll,rr;
	spt(rt,l,r,x);
	spt(l,ll,rr,x-1);
	rr=mg(tr[rr].ls,tr[rr].rs);
	rt=mg(mg(ll,rr),r);
}
int kth(int u,int key){
	int p=tr[tr[u].ls].sz+1;
	if(p==key){
		return tr[u].id;
	}
	if(p<key){
		return kth(tr[u].rs,key-p);
	}
	else{
		return kth(tr[u].ls,key);
	}
}
int vis[N];
int nvl[N];
void ck(int v){
	int l,r;
	spt(rt,l,r,v-1);
	int id=kth(l,1);
	rt=mg(l,r);
	if(id==0){
		return;
	}
	del(nvl[id]);
	nvl[id]=v;
	ins(nvl[id],id);
}
signed main(){
//	freopen("buy3.in","r",stdin);
//	freopen("buy3.out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>w[i].a>>w[i].b;
	}
	for(int i=1;i<=m;i++){
		cin>>q[i].w>>q[i].v;
	}
	sort(w+1,w+n+1,cp);
	sort(q+1,q+m+1,cmp);
	int Z=1;
	for(int i=1;i<=n;i++){
		nvl[i]=w[i].a-w[i].b;
	}
	queue<int> qu;
	for(int i=1;i<=m;i++){
		qu.push(i);
		if(q[i+1].w==q[i].w){
			continue;
		}
		while(w[Z].a>=q[i].w&&Z<=n){
			ins(nvl[Z],Z);
			Z++;
		}
		while(!qu.empty()){
			int u=qu.front();
			qu.pop();
			ck(q[u].v);
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		ans+=w[i].a-nvl[i];
	}
	cout<<ans;
	return 0;
}

思路是用排序干掉w这一维,然后把优惠力度(a-b)放到平衡树里,每次让一个小于v的平衡树里的最小元素变为这个优惠v

2024/11/9 14:20
加载中...