经过推敲可以发现,这种运算的最后结果,只和末尾1的个数有关
(还和1前面的一两个数字有关,要看情况判断)
所以想办法记录两端最后一个0的位置就好
因为两边都可以进行push,pop操作,所以开一个400000的数组,从中间开始操作
那么记录0的位置,push,pop,query都是O(1)的操作
对于反转就直接换一边操作即可,也是O(1)
总时间复杂度O(n)
我这里用了线段树,时间复杂度是O(nlogn)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 400000 + 100;
int l[N << 2], r[N << 2];
int ll, rr;
void push_up(int rt)
{
if (l[rt << 1])
l[rt] = l[rt << 1];
else
l[rt] = l[rt << 1 | 1];
if (r[rt << 1 | 1])
r[rt] = r[rt << 1 | 1];
else
r[rt] = r[rt << 1];
}
void build(int l0, int r0, int rt)
{
if (l0 == r0)
{
l[rt] = r[rt] = 0;
return;
}
int m = (l0 + r0) >> 1;
build(l0, m, rt << 1);
build(m + 1, r0, rt << 1 | 1);
push_up(rt);
}
void update(int p, int f, int l0, int r0, int rt)
{
if (l0 == r0 && l0 == p)
{
if (!f)
{
l[rt] = p;
r[rt] = p;
}
else
l[rt] = r[rt] = 0;
return;
}
int m = (l0 + r0) >> 1;
if (p <= m)
update(p, f, l0, m, rt << 1);
else
update(p, f, m + 1, r0, rt << 1 | 1);
push_up(rt);
}
int main()
{
int T, kase = 0;
scanf("%d", &T);
int n;
while (T--)
{
scanf("%d", &n);
char s[10];
int x;
build(1, 400000, 1);
ll = 200001;
rr = 200000;
bool flag = false;
printf("Case #%d:\n", ++kase);
while (n--)
{
scanf("%s", s);
if (s[0] == 'P' && s[1] == 'U')
{
scanf("%d", &x);
if (flag)
{
ll--;
if (x == 0)
update(ll, 0, 1, 400000, 1);
}
else
{
rr++;
if (x == 0)
update(rr, 0, 1, 400000, 1);
}
}
else if (s[0] == 'P' && s[1] == 'O')
{
if (flag)
{
update(ll, 1, 1, 400000, 1);
ll++;
}
else
{
update(rr, 1, 1, 400000, 1);
rr--;
}
}
else if (s[0] == 'R')
{
flag = !flag;
}
else if (s[0] == 'Q')
{
int len;
if (rr < ll)
{
printf("Invalid.\n");
continue;
}
if (l[1] == 0)
{
len = rr - ll + 1;
if (len & 1)
printf("1\n");
else
printf("0\n");
continue;
}
if (!flag)
{
len = l[1] - ll;
if (rr > l[1])
{
if (len & 1)
printf("0\n");
else
printf("1\n");
}
else
{
if (len & 1)
printf("1\n");
else
printf("0\n");
}
}
else
{
len = rr - r[1];
if (ll < r[1])
{
if (len & 1)
printf("0\n");
else
printf("1\n");
}
else
{
if (len & 1)
printf("1\n");
else
printf("0\n");
}
}
}
}
}
return 0;
}