题意就是开始给出n个黑白棋子,然后1.翻转连续的一段,即黑白颜色互换,2.查询连续一段区间里面连续的黑色棋子的最长长度。
hdu 1540是单点更新区间查询,这道是成段更新区间查询,两道的大致思路没什么区别,就是当前节点的maxlen为,当前节点控制范围里左最长连续和右最长连续,或者包括mid在内的一段连续(这里的连续指黑棋的连续区间)。但是不同的是这里还要记录白棋的信息,因为翻转的时候,正好翻转到某一颗子树控制的范围,那么只要去修改这颗子树的信息就好,而子树的信息记录了黑白两种信息的话,只需两种信息互换即可。总之简单区间合并的话还是按照这个套路来的。
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define pi acos(-1.0)
#define eps 1e-8
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 100010;
struct node{
int l, r;
int l1, l0, r1, r0, max1, max0;
int col, len;
}tr[N << 2];
int n, m;
int read()
{
char ch=' ';
int ans=0;
while(ch<'0' || ch>'9')
ch=getchar();
while(ch<='9' && ch>='0')
{
ans=ans*10+ch-'0';
ch=getchar();
}
return ans;
}
void f( int rt )
{
swap( tr[rt].l1, tr[rt].l0 );
swap( tr[rt].r1, tr[rt].r0 );
swap( tr[rt].max1, tr[rt].max0 );
tr[rt].col ^= 1;
}
void pushup( int rt )
{
tr[rt].l1 = tr[rt << 1].l1;
if( tr[rt<<1].l1 == tr[rt<<1].len )
tr[rt].l1 += tr[rt<<1|1].l1;
tr[rt].l0 = tr[rt << 1].l0;
if( tr[rt<<1].l0 == tr[rt<<1].len )
tr[rt].l0 += tr[rt<<1|1].l0;
tr[rt].r1 = tr[rt << 1 | 1].r1;
if( tr[rt<<1|1].r1 == tr[rt<<1|1].len )
tr[rt].r1 += tr[rt<<1].r1;
tr[rt].r0 = tr[rt << 1 | 1].r0;
if( tr[rt<<1|1].r0 == tr[rt<<1|1].len )
tr[rt].r0 += tr[rt<<1].r0;
tr[rt].max1 = max( max(tr[rt<<1].max1, tr[rt<<1|1].max1), tr[rt<<1].r1 + tr[rt<<1|1].l1 );
tr[rt].max0 = max( max(tr[rt<<1].max0, tr[rt<<1|1].max0), tr[rt<<1].r0 + tr[rt<<1|1].l0 );
}
void down( int rt )
{
f( rt << 1 );
f( rt << 1 | 1 );
tr[rt].col = 0;
}
void build( int l, int r, int rt )
{
tr[rt].l = l;
tr[rt].r = r;
tr[rt].len = r - l + 1;
tr[rt].col = 0;
if( l == r )
{
int x;
scanf("%d", &x);
if( x == 1 )
{
tr[rt].l1 = tr[rt].r1 = tr[rt].max1 = 1;
tr[rt].l0 = tr[rt].r0 = tr[rt].max0 = 0;
}
else
{
tr[rt].l1 = tr[rt].r1 = tr[rt].max1 = 0;
tr[rt].l0 = tr[rt].r0 = tr[rt].max0 = 1;
}
return;
}
int mid = ( l + r ) >> 1;
build( lson );
build( rson );
pushup( rt );
}
void update( int l, int r, int rt )
{
if( l <= tr[rt].l && tr[rt].r <= r )
{
f( rt );
return;
}
if( tr[rt].col )
down( rt );
int mid = ( tr[rt].l + tr[rt].r ) >> 1;
if( r <= mid )
update( l, r, rt << 1 );
else if( l > mid )
update( l, r, rt << 1 | 1 );
else
{
update( lson );
update( rson );
}
pushup( rt );
}
int query( int l, int r, int rt )
{
if( l <= tr[rt].l && tr[rt].r <= r )
return tr[rt].max1;
if( tr[rt].col )
down( rt );
int mid = ( tr[rt].l + tr[rt].r ) >> 1;
int z, x, minn;
if( r <= mid )
return query( l, r, rt << 1 );
else if( l > mid )
return query( l, r, rt << 1 | 1 );
else
{
z = query( lson );
x = query( rson );
minn = min( mid - l + 1, tr[rt<<1].r1 ) + min( r - mid, tr[rt<<1|1].l1 );
return max( max( z, x ), minn );
}
}
int main()
{
while( ~scanf("%d", &n) )
{
build( 1, n, 1 );
scanf("%d", &m);
while( m -- )
{
int op, a, b;
scanf("%d%d%d", &op, &a, &b);
if( op == 1 )
update( a, b, 1 );
else
{
int ans = query( a, b, 1 );
printf("%d\n", ans);
}
}
}
return 0;
}