首页 > 代码库 > Hdu 3397 Sequence operation(线段树多操作,Lazy思想,成段更新)
Hdu 3397 Sequence operation(线段树多操作,Lazy思想,成段更新)
Sequence operation
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6397 Accepted Submission(s): 1899
Problem Description
lxhgww got a sequence contains n characters which are all ‘0‘s or ‘1‘s.
We have five operations here:
Change operations:
0 a b change all characters into ‘0‘s in [a , b]
1 a b change all characters into ‘1‘s in [a , b]
2 a b change all ‘0‘s into ‘1‘s and change all ‘1‘s into ‘0‘s in [a, b]
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]
We have five operations here:
Change operations:
0 a b change all characters into ‘0‘s in [a , b]
1 a b change all characters into ‘1‘s in [a , b]
2 a b change all ‘0‘s into ‘1‘s and change all ‘1‘s into ‘0‘s in [a, b]
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]
Input
T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, ‘0‘ or ‘1‘ separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, ‘0‘ or ‘1‘ separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
Output
For each output operation , output the result.
Sample Input
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
Sample Output
5 2 6 5
Author
lxhgww&&shǎ崽
Source
HDOJ Monthly Contest – 2010.05.01
Recommend
lcy | We have carefully selected several similar problems for you: 1828 1542 1540 2871 1255
题目大意:
0 a b将区间[a,b]所有数全部变成0
1 a b将区间[a,b]所有数全部变成1
2 a b将区间[a,b]中所有数0 1互换,0变1,1变0
3 a b输出区间[a,b]中1的个数
4 a b输出区间[a,b]中最长连续1的个数
题解:
分别记录节点左右中最长连续1和0,op标记区间更新为1或0,xo则标记异或。
CODE:
#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思想,成段更新)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。