标签: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