CF 908F New Year and Rainbow Roads Thinking, Greed, Unicom

The meaning of the question: There are n points on the x-axis, with three colors (BRP) respectively. The cost of connecting the two points is the distance.
When the red point R is required to be deleted, any two points in the BP can be connected. It is
required to delete the blue point. When the color point is B, any two points in RP can be connected.
n<=2e5, -1e9<=x[i]<=1e9. What is the minimum cost of edge building that satisfies the above conditions?


If there is no point P, connect adjacent ones B, and the adjacent R can be connected.


Example: RPR Obviously this is connected to RPR, and the priority than [RR, RP] will
connect the adjacent points before the first P in turn, and the phase after the last P will be connected in turn. Adjacent points are connected in turn.
Then the situation between two adjacent Ps can be considered independently, P....P, first consider B, and then R is also considered similarly.


Case 1: Adjacent Ps are not connected, and the phases are connected respectively. Adjacent B, BP is enough.
Case 2: Connect adjacent P, Pb[1],b[2],...b[i]...b[k],P A total of k+2 point edges They are definitely adjacent.

Only k+1 edges are needed to connect. So remove the edge with the largest adjacent distance.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+5;
ll n,x;
char op[2];
struct node{
	ll x;
	char on;
}a[N];
ll res=0;
void calc()
{
	ll mxR = -2e9, mxB = -2e9, mnR = 2e9, mnB = 2e9;
	for(int j=1;j<=n;j++)
	{
		if(a[j].op=='R')
			mxR=max(mxR,a[j].x),mnR=min(mnR,a[j].x);
		if(a[j].op=='B')
			mxB=max(mxB,a[j].x),mnB=min(mnB,a[j].x);
	}
	if(mxR!=-2e9)
		res + = mxR-mnR;
	if(mxB!=-2e9)
		res+=mxB-mnB;
	cout<<res<<'\n';
	exit(0);
}
intmain()
{
	scanf("%I64d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%I64d%s",&a[i].x,op);
		a[i].op=op[0];
	}	
	int st=-1,ed=-1;
	for(int i=1;i<=n;i++)
		if(a[i].op=='P')
		{
			ll mnR=2e9,mnB=2e9;
			for(int j=1;j<i;j++)
			{
				if(a[j].op=='R') mnR=min(mnR,a[j].x);
				if(a[j].op=='B') mnB=min(mnB,a[j].x);
			}
			if(mnR!=2e9)
				res+=a[i].x-mnR;
			if(mnB!=2e9)
				res+=a[i].x-mnB;
			st=i;
			break;
		}
	if(st==-1)
		calc();
	for(int i=n;i>=1;i--)
		if(a[i].op=='P')
		{	
			ll mxR=-2e9,mxB=-2e9;
			for(int j=i+1;j<=n;j++)
			{
				if(a[j].op=='R')	mxR=max(mxR,a[j].x);
				if(a[j].op=='B')	mxB=max(mxB,a[j].x);
			}
			if(mxR!=-2e9)
				res+=mxR-a[i].x;
			if(mxB!=-2e9)
				res+=mxB-a[i].x;
			ed=i;
			break;
		}
	for(int i=st,j=i;i!=ed;i=j)
	{
		j++;
		while(j<=n&&a[j].op!='P')
			j++;
		ll mn=1e18,sum=0;
		ll pr=a[i].x,pb=a[i].x,mr=0,mb=0;
		for(int k=i;k<j;k++)
		{
			if(a[k].op=='R')
			{
				mr=max(mr,a[k].x-pr);
				pr=a[k].x;
			}
			if(a[k].op=='B')
			{
				mb=max(mb,a[k].x-pb);
				pb=a[k].x;
			}
		}
		if(pb!=a[i].x)
			mb=max(mb,a[j].x-pb),sum+=a[j].x-a[i].x-mb;
		if(pr!=a[i].x)
			mr=max(mr,a[j].x-pr),sum+=a[j].x-a[i].x-mr;
		if(pb!=a[i].x&&pr!=a[i].x)
			mn = min (mn, 2ll*(a [j] .xa [i] .x));
		sum+=a[j].x-a[i].x;
		mn=min(mn,sum);
		res+=mn;		
	}
	cout<<res<<'\n';
	return 0;
}

Each B and R will not cross the edge of P, so when p is encountered, the current p position can be regarded as the last B and R, which greatly simplifies the amount of code

#include<bits/stdc++.h>
#define MAXN 300005
#define INF 1000000000
#define MOD 1000000007
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
ll n,x,lastr,lastb,lastp,mr,mb,ans=0;
char ch;
intmain()
{
	scanf("%I64d",&n);
	bool pp=false,bb=false,rr=false;
	for(ll i=1;i<=n;i++)
	{
		scanf("%I64d %c",&x,&ch);
		if(ch=='R'||ch=='P')
		{
			if(rr)
			{
				ans+=x-lastr;
				mr=max(mr,x-lastr);
			}
			rr=true;
			lastr=x;
		}
		if(ch=='B'||ch=='P')
		{
			if(bb)
			{
				ans+=x-lastb;
				mb=max(mb,x-lastb);
			}
			bb=true;
			lastb=x;
		}
		if(ch=='P')
		{
			if(pp)ans+=min(0LL,x-lastp-mr-mb);
			lastp=x;mr=0;mb=0;pp=true;
		}
	}
	printf("%I64d\n",ans);
	return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326401988&siteId=291194637