0 a b change all characters into '0's in [a , b] //把a,b间的都改为0
1 a b change all characters into '1's in [a , b] //把a,b间都改为1
2 a b change all '0's into '1's and change all '1's into '0's in
[a, b] //1的改为0,0的改为1
Output operations:
3 a b output the number of '1's in [a, b]
的数量
4 a b output the length of the longest continuous '1' string in [a
, b]//a,b间最大连续的1的个数
思路:经典的线段树,只是操作过多,但其实很简单,相当于把以前做过的题的操作合在一块 什么值的更改,区间和的查询,最开连续的个数
。所以没什么特殊的
//1312MS
8836K
#include <stdio.h>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define M 100010
struct tree
{
l,r,len;
sum,cover;
有3个值-1,0,1分别表示该区间是否被0,1完全覆盖
lm,rm,ma;
//lm rm ma 分别表示 左连续 右连续 和最大的连续1的个数
} node[M*4];
int num[M];
int max (int a,int b)
{
> b ? a : b;
}
int min (int a ,int b)
{
> b ? b : a;
}
void Union (int u)
{
//常用手法 就不多解释了
= node[L(u)].sum + node[R(u)].sum;
(node[L(u)].len == node[L(u)].lm)
node[u].lm = node[L(u)].len + node[R(u)].lm;
node[u].lm = node[L(u)].lm;
(node[R(u)].len == node[R(u)].rm)
node[u].rm = node[R(u)].len + node[L(u)].rm;
node[u].rm = node[R(u)].rm;
(node[L(u)].ma,node[R(u)].ma);
(node[u].lm,node[u].rm);
max (max (a,b),node[L(u)].rm + node[R(u)].lm);
}
void Build (int u,int left,int right)
{
left;
right;
= right - left + 1;
node[u].cover = -1;
right)
if (num[left])
{
node[u].sum = 1;
node[u].cover = 1;
node[u].lm = node[u].rm = node[u].ma = 1;
}
else
{
node[u].sum = 0;
node[u].cover = 0;
node[u].lm = node[u].rm = node[u].ma = 0;
}
return ;
(left + right)>>1;
(L(u),left,mid);
(R(u),mid+1,right);
(u);
}
void getdown (int
u)