[ABC426F]Clearance题解

Time Limit: 5 sec / Memory Limit: 1024 MiB

Score : 525 points

Problem Statement

AtCoder Inc.'s online shop currently handles N products, and the stock of product i is Ai​ units remaining.

Process the following Q orders in order. The i-th order is as follows:

  • Buy ki​ units each of products li​,li​+1,…,ri​. For products with fewer than ki​ units, buy all available units. Report the total number of products bought in this order.

Note that for i<Q, the stock of products bought in the i-th order is reduced before proceeding to the (i+1)-th order.

有道 翻译

问题陈述

AtCoder Inc.的网上商店目前处理 N 产品,产品 i 的库存为 Ai​ 单位。

按顺序处理以下 Q 订单。 i \的顺序如下:

-购买 ki​ 单位的产品 li​,li​+1,…,ri​ 。对于少于 ki​ 单位的产品,购买所有可用的单位。报告此订单中购买的产品总数。

请注意,对于 i<Q ,在继续进行 (i+1) \第一个订单之前,在 i \第一个订单中购买的产品库存会减少。

Constraints

  • All input values are integers.
  • 1≤N≤3×105
  • 1≤Ai​≤1015
  • 1≤Q≤3×105
  • 1≤li​≤ri​≤N
  • 1≤ki​≤109

有道 翻译

# #约束

—所有输入值均为整数。

—— 1≤N≤3×105

—— 1≤Ai​≤1015

—— 1≤Q≤3×105

—— 1≤li​≤ri​≤N

—— 1≤ki​≤109


Input

The input is given from Standard Input in the following format:

N
A1​ A2​ … AN​
Q
l1​ r1​ k1​
l2​ r2​ k2​
⋮
lQ​ rQ​ kQ​

有道 翻译

# #输入

输入来自标准输入,格式如下:

N
A1​ A2​ … AN​
Q
l1​ r1​ k1​
l2​ r2​ k2​
⋮
lQ​ rQ​ kQ​

Output

Output Q lines.
The i-th line should contain the total number of products bought in the i-th order.

有道 翻译

# #输出

输出 Q 行。

i \第一行应该包含 i \第一个订单中购买的产品总数。


Sample Input 1

Copy

6
2 6 4 5 7 5
5
1 6 1
3 5 4
4 4 1
2 5 1
1 6 100

Sample Output 1

Copy

6
11
0
2
10

This input contains 5 orders.

  • Initially, the stocks of the products are (from product 1 onward) 2,6,4,5,7,5 units.
  • The first order is l1​=1,r1​=6,k1​=1.
    • In this order, 1,1,1,1,1,1 units of the products are bought, for a total of 6 units.
    • After this, the stocks of the products become 1,5,3,4,6,4 units.
  • The second order is l2​=3,r2​=5,k2​=4.
    • In this order, 0,0,3,4,4,0 units of the products are bought, for a total of 11 units.
    • After this, the stocks of the products become 1,5,0,0,2,4 units.
  • The third order is l3​=4,r3​=4,k3​=1.
    • In this order, 0,0,0,0,0,0 units of the products are bought, for a total of 0 units.
    • After this, the stocks of the products become 1,5,0,0,2,4 units.
  • The fourth order is l4​=2,r4​=5,k4​=1.
    • In this order, 0,1,0,0,1,0 units of the products are bought, for a total of 2 units.
    • After this, the stocks of the products become 1,4,0,0,1,4 units.
  • The fifth order is l5​=1,r5​=6,k5​=100.
    • In this order, 1,4,0,0,1,4 units of the products are bought, for a total of 10 units.
    • After this, the stocks of the products become 0,0,0,0,0,0 units.

有道 翻译

###输出示例

6
11
0
2
10

这个输入包含 5 个订单。

-最初,产品的库存为(从产品 1 开始) 2,6,4,5,7,5 个单位。

—第一个订单为 l1​=1,r1​=6,k1​=1 。

-在此订单中,购买了 1,1,1,1,1,1 件产品,共计 6 件。

-在此之后,产品的库存变为 1,5,3,4,6,4 个单位。

—第二个订单为 l2​=3,r2​=5,k2​=4 。

-在此订单中,购买 0,0,3,4,4,0 件产品,共计 11 件。

-在此之后,产品的库存变为 1,5,0,0,2,4 单位。

—第三阶为 l3​=4,r3​=4,k3​=1 。

-在此订单中,购买了 0,0,0,0,0,0 件产品,共计 0 件。

-在此之后,产品的库存变为 1,5,0,0,2,4 单位。

—第四个顺序为 l4​=2,r4​=5,k4​=1 。

-在此订单中,购买了 0,1,0,0,1,0 件产品,共计 2 件。

-在此之后,产品的库存变为 1,4,0,0,1,4 个单位。

—第五阶为 l5​=1,r5​=6,k5​=100 。

-在此订单中,购买了 1,4,0,0,1,4 件产品,共计 10 件。

-在此之后,产品的库存变为 0,0,0,0,0,0 单位。

思路

注意到有区间加减操作,考虑线段树解答,注意到有小于取全部操作,所以记录和,最小值,剩余货物种数,每一次出现货物耗尽,则单独修改并删除。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long n,a[300005],q,l[300005],r[300005],k[300005];
long long te[4000006],tem[4000006],lz[4000006],xx,siz[4000006];
void alz(int a1,long long v){
	if(tem[a1]<=1e18){
		te[a1]-=siz[a1]*v;
		tem[a1]-=v;
		lz[a1]+=v;		
	}
}//a1打标记值v
void dow(int a1){
	alz(a1*2,lz[a1]);
	alz(a1*2+1,lz[a1]);
	lz[a1]=0;
}//a1下发标记至儿子
void bu(int a1,int l,int r){
	siz[a1]=r-l+1;
	lz[a1]=0;
	if(l==r){
		te[a1]=a[l];
		tem[a1]=a[l];
		return ;
	}
	int mid=(l+r)/2;
	bu(a1*2,l,mid);
	bu(a1*2+1,mid+1,r);
	te[a1]=te[a1*2]+te[a1*2+1];
	tem[a1]=min(tem[a1*2],tem[a1*2+1]);
	return ;
}//l~r建树节点a1
void ci(int a1,int l,int r,int x,int y,long long v){
	if(l>=x&&r<=y){
		if(tem[a1]>=v){
			if(tem[a1]<=1e18){
				te[a1]-=siz[a1]*v;
				tem[a1]-=v; 
				lz[a1]+=v;				
			} 
		}
		else if(l!=r){
			int mid=(l+r)/2;
			dow(a1);
			//if(tem[a1*2]<=v-1){
				ci(a1*2,l,mid,x,y,v);
			//}
			//if(tem[a1*2+1]<=v-1){
				ci(a1*2+1,mid+1,r,x,y,v);
			//}	
			te[a1]=te[a1*2]+te[a1*2+1];
			tem[a1]=min(tem[a1*2],tem[a1*2+1]);
			siz[a1]=siz[a1*2]+siz[a1*2+1];		
		}
		else{
			te[a1]=0;
			tem[a1]=1e18+7;
			siz[a1]=0;
		}
		return ;
	}
	int mid=(l+r)/2;
	dow(a1);
	if(x<=mid){
		ci(a1*2,l,mid,x,y,v);
	}
	if(mid+1<=y){
		ci(a1*2+1,mid+1,r,x,y,v);
	}
	te[a1]=te[a1*2]+te[a1*2+1];
	tem[a1]=min(tem[a1*2],tem[a1*2+1]);
	siz[a1]=siz[a1*2]+siz[a1*2+1];
	return ;
}//x~y区间加v至l~r区间a1点
long long co(int a1,int l,int r,int x,int y,int v){
	if(x<=l&&r<=y){
		if(tem[a1]>=v){
			if(tem[a1]<=1e18){
				return v*siz[a1];				
			} 
			else{
				return 0;
			}
		}
		else if(l!=r){
			int mid=(l+r)/2;
			long long dbdb=0;
			dow(a1);
			//if(tem[a1*2]<=v-1){
				dbdb+=co(a1*2,l,mid,x,y,v);
			//}
			//if(tem[a1*2+1]<=v-1){
				dbdb+=co(a1*2+1,mid+1,r,x,y,v);
			//}	
			te[a1]=te[a1*2]+te[a1*2+1];
			tem[a1]=min(tem[a1*2],tem[a1*2+1]);
			siz[a1]=siz[a1*2]+siz[a1*2+1];
			return dbdb;		
		}
		else{
			return te[a1];
		}
	}
	int mid=(l+r)/2;
	long long dbdb=0;
	dow(a1);
	if(mid>=x){
		dbdb+=co(a1*2,l,mid,x,y,v);
	}
	if(mid+1<=y){
		dbdb+=co(a1*2+1,mid+1,r,x,y,v);
	}
	te[a1]=te[a1*2]+te[a1*2+1];
	tem[a1]=min(tem[a1*2],tem[a1*2+1]);
	siz[a1]=siz[a1*2]+siz[a1*2+1];
	return dbdb;
}//x~y区间问至l~r区间a1点	
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i]; 
	}
	bu(1,1,n);
	cin>>q;
	for(int i=1;i<=q;i++){
		cin>>l[i]>>r[i]>>k[i];
		cout<<co(1,1,n,l[i],r[i],k[i])<<endl;
		ci(1,1,n,l[i],r[i],k[i]);
	}
	return 0;
}

posted @ 2025-10-04 21:46  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源