【悬赏 3 关注】萌新求助,2.34k,20pts。
查看原帖
【悬赏 3 关注】萌新求助,2.34k,20pts。
286448
Eason2009楼主2022/9/25 10:58
#include <bits/stdc++.h>
#define int long long
#define maxn 1000005
#define ls now<<1
#define rs now<<1|1
int n,a[maxn],b[maxn],id[maxn],c,mn;
struct node
{
	int minn,tag1,tag2,tag3;
}tree[maxn*8];
using namespace std;
void pushdown2(int now)//推平标记下放 
{
	if(!tree[now].tag3) return;
	tree[ls].minn=tree[rs].minn=tree[now].minn;
	tree[ls].tag1=tree[rs].tag1=0;
	tree[ls].tag2=tree[rs].tag2=0;
	tree[ls].tag3=tree[rs].tag3=1;
	tree[now].tag3=0;
	return;
}
void pushdown1(int l,int r,int now)
{
	pushdown2(now);
	pushdown2(ls),pushdown2(rs);
	int mid=l+r>>1;
	if(tree[now].tag1)
	{
		tree[ls].minn+=tree[now].tag1,tree[ls].tag1+=tree[now].tag1;
		tree[rs].minn+=tree[now].tag1,tree[rs].tag1+=tree[now].tag1;
		tree[now].tag1=0;
	}
	if(tree[now].tag2)
	{
		tree[ls].minn+=tree[now].tag2*b[mid],tree[ls].tag2+=tree[now].tag2;
		tree[rs].minn+=tree[now].tag2*b[r],tree[rs].tag2+=tree[now].tag2;
		tree[now].tag2=0;
	}
	return;
}
void pushup(int now)
{
	tree[now].minn=min(tree[ls].minn,tree[rs].minn);
	return;
}
void modify1(int l,int r,int now,int qr,int x,int y)
{
	int mid=l+r>>1;
	if(l!=r) pushdown1(l,r,now);
	if(l>qr)
	{
		pushdown2(now);
		tree[now].minn+=y;
		tree[now].tag1+=y;
		return;
	}
	else if(r<=qr)
	{
		pushdown2(now);
		tree[now].minn+=x;
		tree[now].tag1+=x;
		tree[now].minn+=b[r];
		tree[now].tag2++;
		if(r==qr) mn=tree[now].minn;
		return;
	}
	modify1(l,mid,ls,qr,x,y);
	modify1(mid+1,r,rs,qr,x,y);
	pushup(now);
	return;
}
bool modify2(int l,int r,int now,int qr,int x)//线段树上二分找区间推平点 
{
	int mid=l+r>>1;
	if(l!=r) pushdown1(l,r,now);
	if(l>qr)
	{
		if(tree[now].minn>x)
		{
			tree[now].minn=x;
			tree[now].tag1=tree[now].tag2=0;
			tree[now].tag3=1;
			return 1;
		}
		if(l!=r)
		{
			if(modify2(l,mid,ls,qr,x)) modify2(mid+1,r,rs,qr,x);
		}
		return 0;
	}
	else if(l==r) return 0;
	else if(mid>qr)
	{
		if(modify2(l,mid,ls,qr,x)) modify2(mid+1,r,rs,qr,x);
		return 0;
	}
	return modify2(mid+1,r,rs,qr,x);
}
signed main()
{
	cin>>n>>c;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		b[i]=a[i];
	}
	sort(b+1,b+n+1);
	int m=unique(b+1,b+n+1)-b-1;
	for(int i=1;i<=n;i++)
	{
		id[i]=m-(lower_bound(b+1,b+m+1,a[i])-b)+1;
	}
	reverse(b+1,b+m+1);
	for(int i=1;i<=n;i++)
	{
		modify1(1,m,1,id[i],-a[i],c);
		modify2(1,m,1,id[i],mn);
	}
	cout<<tree[1].minn;
	return 0;
}
2022/9/25 10:58
加载中...