NOIP模拟(10.27)T1 寿司

来源:互联网 发布:知乎手机版搜问题 编辑:程序博客网 时间:2024/04/28 17:36

寿司

题目背景:

10.27 NOIP模拟T1

分析:暴力

 

老子有句喵喵喵真的非常想讲······

觉得今天T1最难的一定不是只有我,T1代码最长的也一定不是只有我,总之这个真的叫T1吗,不过给我留了50分我还真是谢谢你了······

直接讲题吧,考虑如果我们先不考虑成环的问题,那么很显然的我们需要将B给移到两边,或者R移到两边,我们这里直接说R吧,显然,这样做的答案,应该是,每一个被移到左边去的R左边原来的B的个数,每一个被移到右边去的R右边原来的B的个数,那么很显然的,我们最好的方式是将,第(B的总个数 + 1) / 2B(以下将第(B的总个数 + 1) / 2B的位置简称为pos)左边的R全部移到左边,右边的R移到右边,现在我们就有了一种很暴力的O(n2)做法了,就是将这个串的n个循环同构串都这么找到中间的B然后统计一下答案,取最小就好了,显然我们看看数据范围,还是停止了这种naïve的想法······考虑如何在循环同构的过程中维护第(B的总个数 + 1) / 2B所在的位置和当前的答案,考虑每一次更改我们都将当前字符串的第一个字符移到最后去,假如这一个字符为B,那么如果我们原来的pos不移动,那么就是原来pos左边的所有R的贡献都会减少1pos右边的都会加上1,这样就维护了答案,再考虑如何移动pos,显然,我们只需要往后面找到下一个B所在的位置就是新的pos了,那么在移动过程中就有很多的R从原来的pos右边,变成了pos左边,那么我们减去它右边的B的数量,加上它左边的B的数量就可以了。这些操作都可以通过维护RB的前缀和来比较方便的完成。复杂度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;}

原创粉丝点击