链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
小王家的后院有一块菜园,并且小王非常的喜欢吃韭菜,这天小王打算在自家的菜园种植韭菜。
起初小王种植了n棵韭菜的种子,此时n棵韭菜的高度都为0,由于小王每天都会给所有的韭菜施肥,所以韭菜生长的速度飞快,但因为韭菜种子质量不同,施肥后每颗韭菜每天以固定a[i]的速度生长。
接下来的日子里,小王有m天想要吃韭菜,对于第D[i]天小王会把所有高度高于B[i]的韭菜收割到B[i],小王想知道每次他收割韭菜的总收割量。
输入描述:
第一行给定一个t,代表t组测试数据。(1<=t<=10)
对于每组数据,给定n,m代表有n棵韭菜,m次收割操作。
(1<=n,m<=1e5,∑n,∑m<=5e5)
接下来一行,给定每棵韭菜每天可以增长的高度a[i]。(1<=a[i]<=1e5)
下面m行,每行给定D[i],B[i],代表第D[i]天收割高于B[i]的韭菜,D[i]保证单调递增。(1<=D[i]<=1e9,1<=B[i]<=1e9)
(数据保证没有任何时刻韭菜高度的总和超出long long范围)
输出描述:
对于每组测试数据输出m行,每行代表收割得到韭菜高度的总和。
示例1
输入
1 4 4 1 3 4 2 1 1 2 0 3 3 4 1000
输出
6 14 1 0
查询时只需要判断区间的最后一棵韭菜的高度a与B的关系,a<=B结束,a>B时,若左儿子的a<=Ba则直接查询右区间,若左儿子的a>Ba直接加上右区间的贡献,继续查询左儿子即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010;
ll a[N];
struct node
{
int l,r;
ll a,b,c,t,H,T;//a最右即最高 b总高度 c总生长速度 t上次收割时间 H T为收割懒标记 高度和时间
}tr[N*4];
void pushup(int u)
{
tr[u].a=tr[u<<1|1].a;
tr[u].b=tr[u<<1|1].b+tr[u<<1].b+(tr[u<<1|1].t-tr[u<<1].t)*tr[u<<1].c;
tr[u].t=tr[u<<1|1].t;
}
void modify(int u,ll T,ll H)
{
tr[u].H=H;
tr[u].T=T;
tr[u].a=H;
tr[u].b=H*(tr[u].r-tr[u].l+1);
tr[u].t=T;
}
void pushdown(int u)
{
if(tr[u].T)
{
modify(u<<1,tr[u].T,tr[u].H);
modify(u<<1|1,tr[u].T,tr[u].H);
tr[u].T=tr[u].H=0;
}
}
void build(int u,int l,int r)
{
if(l==r) tr[u]={l,r,0,0,a[r],0,0,0};
else
{
tr[u]={l,r,0,0,0,0,0,0};
int mid=l+r>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
tr[u].c=tr[u<<1].c+tr[u<<1|1].c;
}
}
ll query(int u,ll T,ll H)
{
ll ans=0;
if(tr[u].l==tr[u].r)
{
if(tr[u].a+tr[u].c*(T-tr[u].t)>H)
{
ans=tr[u].a+tr[u].c*(T-tr[u].t)-H;
modify(u,T,H);
return ans;
}
else return 0;
}
pushdown(u);
if(tr[u<<1|1].a+a[tr[u<<1|1].r]*(T-tr[u<<1|1].t)<=H) return 0;
else if(tr[u<<1].a+a[tr[u<<1].r]*(T-tr[u<<1].t)<=H) ans=query(u<<1|1,T,H);
else
{
ans=query(u<<1,T,H)+tr[u<<1|1].b+(T-tr[u<<1|1].t)*tr[u<<1|1].c-(tr[u<<1|1].r-tr[u<<1|1].l+1)*H;
modify(u<<1|1,T,H);
}
pushup(u);
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
sort(a+1,a+1+n);
build(1,1,n);
ll H,T;
for(int i=1;i<=q;i++)
{
scanf("%lld%lld",&T,&H);
ll res=query(1,T,H);
printf("%lld\n",res);
}
}
}