一个裸的线段树模板:
#include <bits\stdc++.h>
using namespace std;
struct node
{
int min1,l,r,lazy;
}a[400000+5];
void build(int l,int r,int root)
{
a[root].l=l;a[root].r=r;
if(l==r)
{
scanf("%d",&a[root].min1);
return;
}
int mid=(r+l)/2;
build(l,mid,root<<1);
build(mid+1,r,(root<<1)+1);
a[root].min1=min(a[root<<1].min1,a[(root<<1)+1].min1);
}
void pushback(int root,int lazy)
{
a[root].min1-=lazy;
a[root<<1].lazy+=lazy;
a[root*2+1].lazy+=lazy;
}
int query(int l,int r,int root)
{
if(a[root].l>=l&&a[root].r<=r)
return a[root].min1;
if(a[root].lazy>0)
{
pushback(root,a[root].lazy);
a[root].lazy=0;
}
int mid=(a[root].r+a[root].l)/2;
int min1=1e9+7,tmp1=1e9+7;
if(mid>=l)tmp1=query(l,mid,root<<1);
if(mid<r)min1=query(mid+1,r,root*2+1);
min1=min(min1,tmp1);
return min1;
}
void update(int l,int r,int root,int lazy)
{
if(a[root].l>=l&&a[root].r<=r)
{
pushback(root,lazy);
return ;
}
int mid=(a[root].r+a[root].l)/2;
if(mid>=l)update(l,mid,root<<1,lazy);
if(mid<r)update(mid+1,r,root*2+1,lazy);
a[root].min1=min(a[root*2].min1,a[root*2+1].min1);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
memset(a,0,sizeof(a));
long long ans=0;
scanf("%d%d",&n,&k);
build(1,n,1);
for(int i=1;i+k-1<=n;i++)
{
int min1=query(i,i+k-1,1);
ans+=min1;
if(min1==0||i+k-1==n)continue;
update(i+1,i+k-1,1,min1);
}
cout<<ans<<endl;
}
return 0;
}