Luo Gu [P1484] [trees] [greedy] heap

Disclaimer: If you want to reprint, can be explained in the comments directly, thank you! https://blog.csdn.net/SSL_ZYC/article/details/90729664

Subject to the effect:

Topic links: https://www.luogu.org/problemnew/show/P1484
have n n points, wherein select adjacent to each other does not exceed m m points, so that the right and the maximum point.


Ideas:

Thinking problems.
Consider greedy. If we choose the maximum points for the first time i i When, then select two points or points i 1 i-1 sum point i + 1 i+1 election together, or neither of the two.

If we choose to point i 1 i-1 sum point x ( x i + 1 ) x(x≠i+1) , then the greedy thoughts, a [ i 1 ] + a [ x ] a[i-1]+a[x] must be greater than any of a [ q ] + a [ p ] a[q]+a[p] . But when p = i , q = x p=i,q=x time, a [ i > 1 ] + a [ x ] a[i-> 1]+a[x] is certainly less than a [ i ] + a [ x ] a[i]+a[x] (For a start, a [ i ] a[i] is the greatest). contradiction.
QED

If you do not choose a [ i 1 ] a[i-1] and a [ i + 1 ] a[i+1] , then it is a normal greedy. But if you choose a [ i 1 ] a[i-1] and a [ i + 1 ] a[i+1] , then it needs to meet revocable.
If we a [ i ] a[i] is changed to the value of a [ i 1 ] + a [ i + 1 ] a [ i ] a[i-1]+a[i+1]-a[i] , selected again a a array maximum value, a n s years is equal to a [ i ] + a [ i 1 ] + a [ i + 1 ] a [ i ] = a [ i 1 ] + a [ i + 1 ] a[i]+a[i-1]+a[i+1]-a[i]=a[i-1]+a[i+1]

So used to maintain the maximum heap, it can be done O ( m log n ) O(m\log n) complexity


Code:

#include <queue>
#include <cstdio>
#define mp make_pair
using namespace std;
typedef long long ll;

const int N=500010;
int n,m;
bool p[N];
ll a[N],ans;
priority_queue<pair<ll,int> > q;

struct node
{
	int l,r;
}link[N];

int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		q.push(mp(a[i],i));
		link[i].l=i-1; link[i].r=i+1;
	}
	while (m--)
	{
		while (p[q.top().second]) q.pop();
		if (q.top().first<0) break;
		ans+=q.top().first;
		int id=q.top().second;
		a[id]=a[link[id].l]+a[link[id].r]-a[id];
		p[link[id].l]=p[link[id].r]=1;
		link[id].l=link[link[id].l].l; link[link[id].l].r=id;
		link[id].r=link[link[id].r].r; link[link[id].r].l=id;
		q.pop(); q.push(mp(a[id],id));
	}
	printf("%lld",ans);
	return 0;
}

Guess you like

Origin blog.csdn.net/SSL_ZYC/article/details/90729664