[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;
}

浙公网安备 33010602011771号