我们很容易发现,最终孩子一定会在一个RL的地方左右摇摆。

由此,S段自然会分成RRR..RL..LLL如此形式的子串,并且容易发现,这种子串互不相通,即孩子只会在一个子串内移动,绝对不会去到另一个子串里。

同时,我们又可以发现,当一边从交界处开始,第奇数个位置一定会停在交界处。如RRRL,从最右边的R(即交界处)开始数,第奇数个R最终还是会停止最右边的R上(即交界处),因为 1010010^{100} 是个偶数。

如此,我们就很容易发现,当LR的数量和为偶数之时,交界处的RL孩子数量相等!根据如上。

但是如果不是偶数呢?我们依旧可以先看作是偶数的情况,如此就会发现多出了一个字符。同样,根据上面的结论,如果这个字符是第奇数位,则最终会落在自己这边,所以自己这边的边界再补(加)上个一就行了,同理可得,如果不是第奇数位,则在对方的边界再补(加)上个一就行了。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int T = 1;
const int N = 2e5 + 1;
string s;
int arr[N];

void Solve() {
	cin >> s;
	int r = 0, l = 0;//l、r是L、R在子串里的数量
	int idxl, idxr;//交界处下标
	for (int i = 0; i < s.size(); i++) {
    //由此R->L是标记交界
		if (s[i] == 'R') {
			r++;
			if (s[i + 1] == 'L') {
				idxr = i;
				idxl = i + 1;
			}
		} else {//L->R(结束)是计算答案
			l++;
			if (i == s.size() - 1 || s[i + 1] == 'R') {
				arr[idxl] = arr[idxr] = (l + r) / 2;
				if ((l + r) & 1) {//奇数
					if (l > r) {
						if (l & 1) {
							arr[idxl]++;
						} else {
							arr[idxr]++;
						}
					} else {
						if (r & 1) {
							arr[idxr]++;
						} else {
							arr[idxl]++;
						}
					}
				}
				l = r = 0;
			}
		}
	}
	for (int i = 0; i < s.size(); i++) {
		cout << arr[i] << " ";
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	while (T--) {
		Solve();
	}
	return 0;
}

0 条评论

目前还没有评论...