省选专练CTSC2018Day2T1混合果汁Juice

本文分享了一次使用平衡树和主席树解决复杂算法问题的经历。通过对CTSC竞赛中一道难题的解析,揭示了如何利用这些数据结构进行高效查询与更新,特别是针对动态凸包问题的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

天下何人比我弱系列

太难啦!!!

我CTSC花了整整2.5小时才AC

您要是做过CQOI2015任务查询系统就不会蒙蔽了

但是

我是一个SC考生!!!

可怕的ABNS历历在目!!!

那个也是配合饮料!!!

而且是一个可持久化平衡树维护动态二维凸包!!

于是我认为这是一个平衡树维护三维动态凸包

但是我TM又不是傻逼我也知道子任务!!!

于是乎在完成子任务13_15时我想到了主席树!!!

随后->这不就是个原题吗?

水过。

他不是凸包的原因是:这是一个可贪心模型

以d值为根,以p值(离散化)为键值建树查就是了。

唯一的trick还在CQOI2015考过了就是考虑sum是否足够

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int N=1e5*26+10;
const int M=1e5+100;
typedef int INT;
#define LL long long 
#define int long long
inline void read(LL &x){
	x=0;
	int f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
}
LL n;
LL m;
struct Goods{
	LL d,p,l;
	double w;
}e[M];
int root[N]={};
int lson[N]={};
int rson[N]={};
int sum[N]={};
int val[N]={};
int mmp[M]={};
int cnt=1;
void update(int x,int &y,int l,int r,int v,int k){// v is the key
	//cout<<l<<" "<<r<<" "<<k<<'\n';
	cnt++;
	y=cnt;
	lson[y]=lson[x];
	rson[y]=rson[x];
	sum[y]=sum[x]+k;
	val[y]=val[x]+k*mmp[v];
	if(l==r)return;
	//cout<<x<<" "<<y<<" "<<l<<" "<<r<<" "<<sum[y]<<'\n';
	int mid=(l+r)/2;
	if(v<=mid)update(lson[x],lson[y],l,mid,v,k);
	else update(rson[x],rson[y],mid+1,r,v,k);
}
/*int query(int y,int l,int r,int k){
	int t=sum[lson[y]];
	//cout<<y<<" "<<l<<" "<<r<<" "<<k<<" "<<sum[lson[y]]<<" "<<val[lson[y]]<<" "<<t<<'\n';
	if(l==r){
		return k*mmp[l];
	}
	int mid=(l+r)/2;
	if(t<k){
		return val[lson[y]]+query(rson[y],mid+1,r,k-t);
	}
	else return query(lson[y],l,mid,k);
}*/
int query(int x,int y,int l,int r,int k){
	int t=sum[lson[y]]-sum[lson[x]];
	//cout<<y<<" "<<l<<" "<<r<<" "<<k<<" "<<sum[lson[y]]<<" "<<val[lson[y]]<<" "<<t<<'\n';
	if(l==r){
		return k*mmp[l];
	}
	int mid=(l+r)/2;
	if(t<k){
		return val[lson[y]]-val[lson[x]]+query(rson[x],rson[y],mid+1,r,k-t);
	}
	else return query(lson[x],lson[y],l,mid,k);
}
bool cmpC(Goods A,Goods B){
	return A.d<B.d;
}
int d_sum[M]={};
int Maxd=-1;
int len;
bool check(int idx,int l,int g){
	if(d_sum[Maxd]-d_sum[idx-1]<l)
		return false;
	if(query(root[idx-1],root[Maxd],1,len,l)<=g)return true;
	else return false;
}
INT main(){
	freopen("juice.in","r",stdin);
	freopen("juice.out","w",stdout);
	read(n);
	read(m);
	for(int i=1;i<=n;i++){
		read(e[i].d);
		Maxd=max(Maxd,e[i].d);
		read(e[i].p);
		read(e[i].l);	
		d_sum[e[i].d]+=e[i].l;
		mmp[i]=e[i].p;		
	}
	sort(mmp+1,mmp+1+n);
	len=unique(mmp+1,mmp+1+n)-mmp-1;
	for(int i=1;i<=n;i++){
		//cout<<e[i].p<<" ";
		e[i].p=lower_bound(mmp+1,mmp+1+len,e[i].p)-mmp;
		//cout<<e[i].p<<'\n';
	}
	sort(e+1,e+1+n,cmpC);
	e[0].d=0;
	for(int i=1;i<=n;i++){
		//cout<<i<<'\n';
		if(e[i].d!=e[i-1].d){
				for(int l=e[i-1].d+1;l<=e[i].d-1;l++){
					update(root[l-1],root[l],1,len,0,0);
			}
			update(root[e[i].d-1],root[e[i].d],1,len,e[i].p,e[i].l);
		}
		else update(root[e[i].d],root[e[i].d],1,len,e[i].p,e[i].l);
	}
	update(root[Maxd],root[Maxd+1],1,len,0,0);
	//cout<<Maxd<<'\n';
	for(int i=1;i<=Maxd+1;i++){
		d_sum[i]+=d_sum[i-1];
	}
	//cout<<query(root[2],root[Maxd],1,len,3);
	for(int i=1;i<=m;i++){
		int g,l;
		read(g);
		read(l);
		int L=0;
		int R=Maxd+1;
		int ret=-1;
		while(L<=R){
			int mid=(L+R)/2;
			if(check(mid,l,g)){
				ret=mid;
				L=mid+1;
			}
			else R=mid-1;
		}
		printf("%lld\n",ret);
	}
	//cout<<root[2];
	//cout<<query(root[1],root[5],1,len,4);
	//cout<<cnt;
	return 0;
}
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值