标签:hdu3397 sequence operation 线段树 lazy思想 成段更新
1 10 10 0 0 0 1 1 0 1 0 1 1 1 0 2 3 0 5 2 2 2 4 0 4 0 3 6 2 3 7 4 2 8 1 0 5 0 5 6 3 3 9
5 2 6 5
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#define N 100010
#define Mod 10000007
#define lson l,mid,idx<<1
#define rson mid+1,r,idx<<1|1
#define lroot idx<<1
#define rroot idx<<1|1
typedef long long ll;
const int INF = 1000010;
using namespace std;
struct node
{
int lmax, rmax, mmax;///左右中最长连续1
int lm, rm, mm;///左右中最长连续0
int sum;///1的和
int op;///0:标记区间更新为0,1则为1,-1不操作
int xo;
} tree[N << 2];
int a[N];
void pushup ( int idx, int m )
{
tree[idx].sum = tree[lroot].sum + tree[rroot].sum;
///lmax,lm
tree[idx].lmax = tree[lroot].lmax;
tree[idx].lm = tree[lroot].lm;
if ( tree[lroot].lmax == ( m - m / 2 ) )
tree[idx].lmax += tree[rroot].lmax;
else if ( tree[lroot].lm == ( m - m / 2 ) )
tree[idx].lm += tree[rroot].lm;
///rm,rmax
tree[idx].rmax = tree[rroot].rmax;
tree[idx].rm = tree[rroot].rm;
if ( tree[rroot].rmax == m / 2 )
tree[idx].rmax += tree[lroot].rmax;
else if ( tree[rroot].rm == m / 2 )
tree[idx].rm += tree[lroot].rm;
///mm,mmax
tree[idx].mmax = max ( tree[lroot].mmax, tree[rroot].mmax );
tree[idx].mm = max ( tree[lroot].mm, tree[rroot].mm );
tree[idx].mmax = max ( tree[idx].mmax, tree[rroot].lmax + tree[lroot].rmax );
tree[idx].mm = max ( tree[idx].mm, tree[rroot].lm + tree[lroot].rm );
}
void pushdown ( int idx, int m )///m为区间长度
{
if ( m == 1 )
return;
if ( tree[idx].op == 1 )///成段更新为1
{
tree[lroot].op = tree[rroot].op = tree[idx].op;
tree[lroot].sum = tree[lroot].lmax = tree[lroot].rmax = tree[lroot].mmax = m - m / 2;
tree[rroot].sum = tree[rroot].lmax = tree[rroot].rmax = tree[rroot].mmax = m / 2;
tree[rroot].lm = tree[rroot].rm = tree[lroot].lm = tree[lroot].rm = tree[lroot].mm = tree[rroot].mm = 0;
tree[idx].op = -1;
tree[rroot].xo = tree[lroot].xo = 0;
}
else if ( tree[idx].op == 0 )///成段更新为0
{
tree[lroot].op = tree[rroot].op = tree[idx].op;
tree[lroot].sum = tree[lroot].lmax = tree[lroot].rmax = 0;
tree[rroot].sum = tree[rroot].lmax = tree[rroot].rmax = 0;
tree[lroot].mmax = tree[rroot].mmax = 0;
tree[rroot].lm = tree[rroot].rm = tree[rroot].mm = m / 2;
tree[lroot].lm = tree[lroot].rm = tree[lroot].mm = m - m / 2;
tree[idx].op = -1;
tree[rroot].xo = tree[lroot].xo = 0;
}
if ( tree[idx].xo )///1变0,0变1
{
tree[lroot].xo ^= 1;
tree[rroot].xo ^= 1;
tree[lroot].sum = m - m / 2 - tree[lroot].sum;
tree[rroot].sum = m / 2 - tree[rroot].sum;
swap ( tree[lroot].lmax, tree[lroot].lm );
swap ( tree[rroot].lmax, tree[rroot].lm );
swap ( tree[lroot].rmax, tree[lroot].rm );
swap ( tree[rroot].rmax, tree[rroot].rm );
swap ( tree[lroot].mmax, tree[lroot].mm );
swap ( tree[rroot].mmax, tree[rroot].mm );
tree[idx].xo = 0;
}
}
void build ( int l, int r, int idx )
{
tree[idx].xo = 0;
tree[idx].op = -1;
if ( l == r )
{
tree[idx].sum = a[l];
tree[idx].mmax = tree[idx].lmax = tree[idx].rmax = a[l];
tree[idx].mm = tree[idx].rm = tree[idx].lm = a[l] ^ 1;
return;
}
int mid = ( l + r ) >> 1;
build ( lson );
build ( rson );
pushup ( idx, r - l + 1 );
}
void update_1 ( int l, int r, int idx, int begin, int end, int k ) ///更新0->1,1->0成段
{
pushdown ( idx, r - l + 1 );
if ( begin <= l && end >= r )
{
tree[idx].op = k;
tree[idx].xo = 0;
if ( k )
{
tree[idx].sum = r - l + 1;
tree[idx].lmax = tree[idx].rmax = tree[idx].mmax = r - l + 1;
tree[idx].rm = tree[idx].lm = tree[idx].mm = 0;
}
else
{
tree[idx].sum = 0;
tree[idx].lmax = tree[idx].rmax = tree[idx].mmax = 0;
tree[idx].rm = tree[idx].lm = tree[idx].mm = r - l + 1;
}
return;
}
int mid = ( l + r ) >> 1;
if ( begin <= mid )
update_1 ( lson, begin, end, k );
if ( end > mid )
update_1 ( rson, begin, end, k );
pushup ( idx, r - l + 1 );
}
void update_2 ( int l, int r, int idx, int begin, int end ) ///yihuo
{
pushdown ( idx, r - l + 1 );
if ( l >= begin && r <= end )
{
tree[idx].xo = 1;
tree[idx].sum = r - l + 1 - tree[idx].sum;
swap ( tree[idx].lmax, tree[idx].lm );
swap ( tree[idx].rmax, tree[idx].rm );
swap ( tree[idx].mm, tree[idx].mmax );
return;
}
int mid = ( l + r ) >> 1;
if ( begin <= mid )
update_2 ( lson, begin, end );
if ( end > mid )
update_2 ( rson, begin, end );
pushup ( idx, r - l + 1 );
}
int query_1 ( int l, int r, int idx, int begin, int end ) ///查询1的个数
{
pushdown ( idx, r - l + 1 );
if ( begin <= l && end >= r )
return tree[idx].sum;
int mid = ( l + r ) >> 1;
int ans = 0;
if ( begin <= mid )
ans += query_1 ( lson, begin, end );
if ( end > mid )
ans += query_1 ( rson, begin, end );
return ans;
}
int query_2 ( int l, int r, int idx, int begin, int end ) ///查询连续的1的最大长度
{
pushdown ( idx, r - l + 1 );
if ( begin <= l && end >= r )
return tree[idx].mmax;
int mid = ( l + r ) >> 1;
int len = 0;
if ( end > mid )
len = max ( len, query_2 ( rson, begin, end ) );
if ( begin <= mid )
len = max ( len, query_2 ( lson, begin, end ) );
len = max ( len, min ( mid - begin + 1, tree[lroot].rmax ) + min ( end - mid, tree[rroot].lmax ) );
return len;
}
int main()
{
//freopen ( "in.txt", "r", stdin );
int t;
while ( cin >> t )
{
while ( t-- )
{
int n, m;
scanf ( "%d%d", &n, &m );
for ( int i = 1; i <= n; i++ )
scanf ( "%d", &a[i] );
build ( 1, n, 1 );
int begin, end, x;
while ( m-- )
{
scanf ( "%d%d%d", &x, &begin, &end );
begin++, end++;
switch ( x )
{
case 2:
update_2 ( 1, n, 1, begin, end );
break;
case 3:
printf ( "%d\n", query_1 ( 1, n, 1, begin, end ) );
break;
case 4:
printf ( "%d\n", query_2 ( 1, n, 1, begin, end ) );
break;
default:
update_1 ( 1, n, 1, begin, end, x );
}
}
}
}
return 0;
}
Hdu 3397 Sequence operation(线段树多操作,Lazy思想,成段更新)
标签:hdu3397 sequence operation 线段树 lazy思想 成段更新
原文地址:http://blog.csdn.net/acm_baihuzi/article/details/41477701