[CF1599A] Weights

发布时间 2023-09-04 16:07:35作者: 灰鲭鲨

题目描述

You are given an array $ A $ of length $ N $ weights of masses $ A_1 $ , $ A_2 $ ... $ A_N $ . No two weights have the same mass. You can put every weight on one side of the balance (left or right). You don't have to put weights in order $ A_1 $ ,..., $ A_N $ . There is also a string $ S $ consisting of characters "L" and "R", meaning that after putting the $ i-th $ weight (not $ A_i $ , but $ i-th $ weight of your choice) left or right side of the balance should be heavier. Find the order of putting the weights on the balance such that rules of string $ S $ are satisfied.

输入格式

The first line contains one integer $ N $ ( $ 1 \leq N \leq 2*10^5 $ ) - the length of the array $ A $ The second line contains $ N $ distinct integers: $ A_1 $ , $ A_2 $ ,..., $ A_N $ ( $ 1 \leq A_i \leq 10^9 $ ) - the weights given The third line contains string $ S $ of length $ N $ consisting only of letters "L" and "R" - string determining which side of the balance should be heavier after putting the $ i-th $ weight of your choice

输出格式

The output contains $ N $ lines. In every line, you should print one integer and one letter - integer representing the weight you are putting on the balance in that move and the letter representing the side of the balance where you are putting the weight. If there is no solution, print $ -1 $ .

由于样例没有 -1,所以大概率不存在无解情况。

神奇的,考虑把 \(a\) 排序后,对于所有 \(a_i\),将 \(i\) 为偶数的丢一堆, \(i\) 为奇数丢一堆。

具体哪堆丢左边哪堆丢右边看 \(S_n\),因为发现将其从大到小放时,一定是最后丢的那个所在的堆更大,可以用差分证明。

然后考虑把 \(n\) 的问题化为 \(n-1\) 的问题。正着不好做,反着做。发现此时如果拿掉最大的那个砝码所在的地方,天平情况一定会反转,如果拿掉最小的那个砝码,天平情况一定不变。就能从 \(n\) 变为 \(n-1\)

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
const char g[]={'L','R'};
char s[N];
int a[N],n,l=1,r,p[N];
int read()
{
	int s=0;
	char ch=getchar();
	while(ch<'0'||ch>'9')
		ch=getchar();
	while(ch>='0'&&ch<='9')
		s=s*10+ch-48,ch=getchar();
	return s;
}
int main()
{
	r=n=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	sort(a+1,a+n+1);
	scanf("%s",s+1);
	for(int i=n;i^1;i--)
	{
		if(s[i]==s[i-1])
			p[i]=l++;
		else
			p[i]=r--;
	}
	p[1]=l;
	for(int i=1;i<=n;i++)
		printf("%d %c\n",a[p[i]],g[(p[i]&1)^(s[n]=='R')^(n&1)]);
}