题意:
有3中操作:
0 a b 从a到b都置为0
1 a b 从a到b都置成1
2 a b 从a到b都进行异或
2中输出:
3 a b 输出从a到b的1的个数
4 a b 输出从a到b连续的1的个数
思路:
这道题可是坑蒙我了,断断续续能写了几个月。
最近才弄明白些,我原先的思路就是记录0和记录1的,然后异或就把1和0的信息进行互换。
后来才发现正解原来是只需要记一个数组f[10000];
0表示全为0
1表示全为1
-1表示混合的
然后开个全局变量记录长度就可以了;
具体看代码
Code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<stack>
#include<list>
#include<map>
#include<set>
#define TEST
#define LL long long
#define Mt(f, x) memset(f, x, sizeof(f));
#define rep(i, s, e) for(int i = (s); i <= (e); ++i)
#ifdef TEST
#define See(a) cout << #a << " = " << a << endl;
#define See2(a, b) cout << #a << " = " << a << ' ' << #b << " = " << b << endl;
#define debug(a, s, e) rep(_i, s, e) {cout << a[_i] << ' ';} cout << endl;
#define debug2(a, s, e, ss, ee) rep(i_, s, e) {debug(a[i_], ss, ee)}
#else
#define See(a)
#define See2(a, b)
#define debug(a, s, e)
#define debug2(a, s, e, ss, ee)
#endif // TEST
const int MAX = 2e9;
const int MIN = -2e9;
const double eps = 1e-8;
const double PI = acos(-1.0);
using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define ls rt << 1
#define rs rt << 1 | 1
const int N = 100000 + 5;
int f[N << 2], lastR, maxLen, temLen;//lastR是刚刚处理过区间的右边,maxLen, temLen是用来记录长度的
void pushUp(int rt)
{
if(f[ls] == f[rs])
{
f[rt] = f[ls];
}
else
{
f[rt] = -1;
}
}
void build(int l, int r, int rt)
{
if(l == r)
{
scanf("%d", &f[rt]);
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
pushUp(rt);
}
void pushDown(int rt)
{
if(f[rt] >= 0)
{
f[ls] = f[rs] = f[rt];
f[rt] = -1;
}
}
void update(int L, int R, int v, int l, int r, int rt)
{
if(f[rt] == v)
{
return ;
}
if(L <= l && r <= R)
{
f[rt] = v;
return;
}
pushDown(rt);
int m = (l + r) >> 1;
if(L <= m)
update(L, R, v, lson);
if(R > m)
update(L, R, v, rson);
pushUp(rt);
}
void updateXor(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R && f[rt] >= 0)
{
f[rt] ^= 1;
return ;
}
pushDown(rt);
int m = (l + r) >> 1;
if(L <= m)
updateXor(L, R, lson);
if(R > m)
updateXor(L, R, rson);
pushUp(rt);
}
int query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R && f[rt] >= 0)
{
return f[rt] * (r - l + 1);
}
pushDown(rt);
int m = (l + r) >> 1;
if(R <= m)
return query(L, R, lson);
if(L > m)
return query(L, R, rson);
return query(L, R, lson) + query(L, R, rson);
}
void queryL(int L, int R, int l, int r, int rt)
{
if(f[rt] == 0)
{
return ;
}
if(L <= l && r <= R && f[rt] == 1)
{
if(L == lastR + 1)//判断这个区间是否和上个区间连续
{
temLen += r - l + 1;
}
else
{
temLen = r - l + 1;
}
maxLen = max(maxLen, temLen);
lastR = r;
return ;
}
pushDown(rt);
int m = (l + r) >> 1;
if(R <= m)
queryL(L, R, lson);
else if(L > m)
queryL(L, R, rson);
else
queryL(L, m, lson) , queryL(m + 1, R, rson);
}
int main()
{
int T;
cin >> T;
while(T--)
{
int n, Q;
scanf("%d%d", &n, &Q);
build(1, n, 1);
while(Q--)
{
int op, a, b;
scanf("%d%d%d", &op, &a, &b);
a++, b++;
switch(op)
{
case 0:
case 1:
update(a, b, op, 1, n, 1);break;
case 2:
updateXor(a, b, 1, n, 1);break;
case 3:
printf("%d\n", query(a, b, 1, n, 1));break;
case 4:
maxLen = 0, temLen = 0;
lastR = 0;
queryL(a, b, 1, n, 1);
printf("%d\n", maxLen);
break;
}
}
}
return 0;
}