寿司
题目背景:
分析:暴力
老子有句喵喵喵真的非常想讲······
觉得今天T1最难的一定不是只有我,T1代码最长的也一定不是只有我,总之这个真的叫T1吗,不过给我留了50分我还真是谢谢你了······
直接讲题吧,考虑如果我们先不考虑成环的问题,那么很显然的我们需要将B给移到两边,或者R移到两边,我们这里直接说R吧,显然,这样做的答案,应该是,每一个被移到左边去的R左边原来的B的个数,每一个被移到右边去的R右边原来的B的个数,那么很显然的,我们最好的方式是将,第(B的总个数 + 1) / 2个B(以下将第(B的总个数 + 1) / 2个B的位置简称为pos)左边的R全部移到左边,右边的R移到右边,现在我们就有了一种很暴力的O(n2)做法了,就是将这个串的n个循环同构串都这么找到中间的B然后统计一下答案,取最小就好了,显然我们看看数据范围,还是停止了这种naïve的想法······考虑如何在循环同构的过程中维护第(B的总个数 + 1) / 2个B所在的位置和当前的答案,考虑每一次更改我们都将当前字符串的第一个字符移到最后去,假如这一个字符为B,那么如果我们原来的pos不移动,那么就是原来pos左边的所有R的贡献都会减少1,pos右边的都会加上1,这样就维护了答案,再考虑如何移动pos,显然,我们只需要往后面找到下一个B所在的位置就是新的pos了,那么在移动过程中就有很多的R从原来的pos右边,变成了pos左边,那么我们减去它右边的B的数量,加上它左边的B的数量就可以了。这些操作都可以通过维护R,B的前缀和来比较方便的完成。复杂度O(Tn)
Source
/*
created by scarlyw
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <cctype>
#include <queue>
#include <vector>
#include <ctime>
const int MAXN = 2000000 + 10;
const long long INF = 1000000000000000000;
int t, len, n;
int lb[MAXN], lr[MAXN], rb[MAXN], rr[MAXN];
char s[MAXN];
int main() {
std::ios::sync_with_stdio(NULL);
std::cin.tie(NULL), std::cout.tie(NULL);
std::cin >> t;
while (t--) {
std::cin >> (s + 1), len = strlen(s + 1);
long long fans1 = INF;
for (int i = 1; i <= len; ++i) s[i + len] = s[i];
n = len, len *= 2;
for (int i = 1; i <= len; ++i) {
lb[i] = lb[i - 1], lr[i] = lr[i - 1];
if (s[i] == 'B') lb[i]++;
else lr[i]++;
}
for (int i = len; i >= 1; --i) {
rb[i] = rb[i + 1], rr[i] = rr[i + 1];
if (s[i] == 'B') rb[i]++;
else rr[i]++;
}
long long ans1 = 0;
int pos = (lb[n] + 1) / 2, p = -1;
for (int i = 1; i <= n; ++i) {
if (lb[i] == pos) {
p = i;
for (int j = n; j >= i; --j)
if (s[j] == 'R') ans1 += (long long)(rb[j] - rb[n + 1]);
break ;
}
if (s[i] == 'R') ans1 += (long long)lb[i];
}
int head = 1, tail = n;
fans1 = ans1;
while (head <= n) {
if (s[head] == 'B') {
ans1 -= lr[p] - lr[head - 1];
ans1 += rr[p] - rr[++tail], ++head;
while (s[++p] != 'B') {
ans1 += (long long)(lb[p] - lb[head - 1]);
ans1 -= (long long)(rb[p] - rb[tail + 1]);
}
} else head++, tail++;
fans1 = std::min(fans1, ans1);
}
std::cout << fans1 << '\n';
}
return 0;
}