CF1515I Phoenix and Diamonds

27 篇文章 0 订阅
14 篇文章 0 订阅

Description

Solution

  • 假设手上有 r e s res res的空间,考虑每一次让 r e s res res减半,做 l o g log log次即可。
  • 考虑减半的过程,不以 r e s / 2 res/2 res/2为边界,而是以 2 k 2^k 2k为边界,从大到小枚举 k k k,将 [ 1 , 2 k ] [1,2^k] [1,2k]设为轻物品, ( 2 k , 2 k + 1 ] (2^k,2^{k+1}] (2k,2k+1]设为重物品,不妨假设 r e s ≤ 2 k + 1 res\le2^{k+1} res2k+1,需要贪心选使得 r e s ≤ 2 k res\le2^k res2k,那么最多取一个重物品,并且取这个重物品之前所有轻物品都可以取,因此计区间最小前缀和 p p p(最后一个为重物品,前面所有为这个重物品前的轻物品),如果 p ≤ r e s p\le res pres就表明可以在这个区间内取一个重物品,线段树二分下去即可。否则就尽量取轻物品。
  • 因此每一次减半需要一次线段树二分,时间复杂度 O ( n   l o g   n   l o g   w ) O(n\ log\ n\ log\ w) O(n log n log w).
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 200005
#define maxm 19
#define ll long long 
#define inf (ll)1e18+5
using namespace std;

int n,q,i,j,k,id[maxn],L;
struct arr{ll w,v,c; int i;} a[maxn];
int cmp(arr a,arr b){return a.v>b.v||a.v==b.v&&a.w<b.w;}

ll res,sum; int now;

struct val{ll w,v;};
val operator+(val a,val b){return (val){a.w+b.w,a.v+b.v};}
val operator*(val a,ll c){return (val){a.w*c,a.v*c};}
int operator<(val a,val b){return a.w<b.w||a.w==b.w&&a.v>b.v;}
struct SegmentTree{
	int lim,I[maxn*4];
	val ts[maxn*4],tm[maxn*4];
	void newnode(int x,int l){
		if (a[l].w<=lim) {
			ts[x]=(val){a[l].w,a[l].v}*a[l].c;
			tm[x]=(val){inf,0},I[x]=0;
		} else {
			ts[x]=(val){0,0};
			if ((a[l].w<=lim<<1)&&a[l].c) tm[x]=(val){a[l].w,a[l].v},I[x]=l;
			else tm[x]=(val){inf,0},I[x]=0;
		}
	}
	void upd(int x){
		ts[x]=ts[x<<1]+ts[x<<1^1];
		if (tm[x<<1]<ts[x<<1]+tm[x<<1^1])
			tm[x]=tm[x<<1],I[x]=I[x<<1];
		else tm[x]=ts[x<<1]+tm[x<<1^1],I[x]=I[x<<1^1];
	}
	void maketree(int x,int l,int r){
		if (l==r){
			newnode(x,l);return;
		}
		int mid=(l+r)>>1;
		maketree(x<<1,l,mid),maketree(x<<1^1,mid+1,r);
		upd(x);
	}
	void change(int x,int l,int r,int p){
		if (l==r){newnode(x,l);return;}
		int mid=(l+r)>>1;
		if (p<=mid) change(x<<1,l,mid,p);
		else change(x<<1^1,mid+1,r,p);
		upd(x);
	}
	void merge(int x,int l,int r,int L,int R){
		if (l>R||r<L||res<lim) return;
		if (L<=l&&r<=R){
			if (res>=tm[x].w&&I[x]){
				if (l==r) res-=tm[x].w,sum+=tm[x].v,now=l;
				else merge(x<<1,l,(l+r)>>1,L,R),merge(x<<1^1,((l+r)>>1)+1,r,L,R);
				return;
			}
			if (res>=ts[x].w) {res-=ts[x].w,sum+=ts[x].v,now=r;return;}
			else if (l==r) {ll d=res/a[l].w; res-=d*a[l].w,sum+=d*a[l].v,now=l;return;}
		}
		int mid=(l+r)>>1;
		merge(x<<1,l,mid,L,R),merge(x<<1^1,mid+1,r,L,R);
	}
} t[maxm];

int main(){
	freopen("ceshi.in","r",stdin);
	freopen("ceshi1.out","w",stdout);
	scanf("%d%d",&n,&q);
	for(i=1;i<=n;i++) scanf("%lld%lld%lld",&a[i].c,&a[i].w,&a[i].v),a[i].i=i;
	for(i=1;i<=n;i++) k=max(k,(int)a[i].w);
	sort(a+1,a+1+n,cmp);
	for(i=1;i<=n;i++) id[a[i].i]=i;
	L=0; while (1<<L<k) L++;
	for(i=0;i<=L;i++) 
		t[i].lim=1<<i,t[i].maketree(1,1,n);
	while (q--){
		int tp; scanf("%d",&tp);
		if (tp==1||tp==2){
			scanf("%d%d",&j,&k),a[id[k]].c+=(tp==1)?j:-j;
			for(i=0;i<=L;i++) t[i].change(1,1,n,id[k]);
		} else {
			sum=0,now=0; scanf("%lld",&res);
			for(i=L;i>=0&&now<n;i--) 
				t[i].merge(1,1,n,now+1,n);
			printf("%lld\n",sum);
		}
	}
}

### 回答1: Diamonds数据集是一个常用的数据集,包含了53,940个钻石的信息,每个钻石有10个属性:克拉数(carat)、切工(cut)、颜色(color)、净度(clarity)、深度(depth)、表宽比(table)、价格(price)、长度(x)、宽度(y)和深度(z)。这个数据集经常被用来进行数据分析和机器学习的练习,因为它包含了多个类型的特征变量,可以用来预测钻石价格或者其他的属性。 ### 回答2: diamonds数据集是一个经典的数据集,其中包含关于钻石的许多信息。这个数据集由GIA(Gemological Institute of America)收集,包含了53,940个钻石的数据。数据集的列包含了钻石的各种属性,比如克拉重量、切割质量、颜色、净度等等。 首先,数据集包含了钻石的克拉重量属性,这是一个连续的数值特征。这个特征对于了解钻石的大小和价值非常重要,是购买钻石时的一个关键指标。 另外,数据集还提供了钻石的切割质量属性,这是一个分类特征。这个特征描述了钻石的切割工艺质量,切割质量对于钻石的亮度和火彩有着直接的影响,是决定钻石品质的重要因素之一。 此外,数据集还包含了钻石的颜色属性,这也是一个分类特征。钻石的颜色分级是根据其无色到有色的程度来评定的,颜色越透明,钻石的品质越高。 最后,数据集还提供了钻石的净度属性,也是一个分类特征。净度描述了钻石的内部杂质和瑕疵程度,净度越高,钻石的品质越好。 总而言之,diamonds数据集提供了钻石的多个属性和特征,对于研究和了解钻石市场和品质有着重要的意义。研究人员和消费者可以利用这个数据集来进行统计分析、预测模型等等,从而更好地了解和选择钻石。 ### 回答3: diamonds数据集是一个广泛使用的数据集,记录了各种钻石的属性信息,包括重量、颜色、净度、切割质量和价格等。这个数据集包含了53940条数据,每条数据有10个变量。这些变量包括了以下内容: 1. Carat(克拉):钻石的重量,用于衡量钻石的大小。克拉数越高,钻石越大。 2. Cut(切割质量):钻石的切割质量,包括了五个等级:Fair、Good、Very Good、Premium和Ideal。 3. Color(颜色):钻石的颜色,从D到J共有7个等级,其中D表示最无色级别,J表示最黄色级别。 4. Clarity(净度):钻石的净度,用于衡量钻石内部的瑕疵程度。净度由FL(无瑕级别)到I1(包含显眼瑕疵)共有8个等级。 5. Depth(深度):钻石的深度,即钻石顶部到底部的距离占总高度的百分比。深度越大,钻石越深。 6. Table(台宽):钻石的台宽,即钻石顶部的平面面积占总面积的百分比。台宽越大,钻石越扁平。 7. Price(价格):钻石的价格,以美元计算。 8. X(长度):钻石的长度(mm)。 9. Y(宽度):钻石的宽度(mm)。 10. Z(深度):钻石的深度(mm)。 通过分析这个数据集,我们可以了解到钻石的各种属性对价格的影响。可以通过绘制散点图、箱线图和相关性分析来观察这些因素之间的关系。此外,我们还可以利用机器学习算法建立模型来预测钻石的价格。 总的来说,diamonds数据集是一个价值很高的数据集,可以帮助我们研究钻石的属性与价格之间的关系,并且可以用于价格预测等实际应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值