zoukankan      html  css  js  c++  java
  • FZU Problem 2105 Digits Count线段树之延迟更新(插线取线)

    //参考了别人的代码,又改进了一下,只用一个数组进行标记,理解了其实也是很简单的……
    #include <stdio.h> #include <string.h> const int N = 1000005; int c, res, a[N*4][4], flag[N*4][4], len[N*4]; void pushDown( int rt ) { int ls = 2 * rt; int rs = ls | 1; for( int i = 0; i < 4; ++i ) { if( flag[rt][i] == -1 ) continue; if( flag[rt][i] == 0 || flag[rt][i] == 1 ) { a[ls][i] = ( flag[ls][i] = flag[rt][i] ) * len[ls]; a[rs][i] = ( flag[rs][i] = flag[rt][i] ) * len[rs]; flag[rt][i] = -1; } else if( flag[rt][i] == 3 ) { flag[rt][i] = -1; } else { a[ls][i] = len[ls] - a[ls][i]; if( flag[ls][i] == -1 ) flag[ls][i] = 2; else flag[ls][i] ^= 1; a[rs][i] = len[rs] - a[rs][i]; if( flag[rs][i] == -1 ) flag[rs][i] = 2; else flag[rs][i] ^= 1; flag[rt][i] = -1; } } } void pushUp( int rt ) { int ls = 2 * rt; int rs = ls | 1; for( int i = 0; i < 4; ++i ) a[rt][i] = a[ls][i] + a[rs][i]; } void build( int l, int r, int rt ) { len[rt] = r - l + 1; if( l == r ) { scanf("%d", &c); for( int i = 0; i < 4; ++i ) a[rt][i] = ( 1 & (c>>i) ); } else { int mid = ( l + r ) / 2; build(l, mid, 2 * rt); build(mid + 1, r, 2 * rt + 1); pushUp( rt ); } } void OR( int rt, int opn ) { for( int i = 0; i < 4; ++i ) { if( !( (opn>>i) & 1 ) ) continue; flag[rt][i] = 1; a[rt][i] = len[rt]; } } void ADD( int rt, int opn ) { for( int i = 0; i < 4; ++i ) { if( (opn>>i) & 1 ) continue; flag[rt][i] = 0; a[rt][i] = 0; } } void XOR( int rt, int opn ) { for( int i = 0; i < 4; ++i ) { if( !( (opn>>i) & 1 ) ) continue; if( flag[rt][i] == -1 ) flag[rt][i] = 2; else flag[rt][i] ^= 1; a[rt][i] = len[rt] - a[rt][i]; } } void query( int l, int r, int rt, int aa, int bb ) { if( aa <= l && r <= bb ) { res = res + a[rt][0] + a[rt][1] * 2 + a[rt][2] * 4 + a[rt][3] * 8; return; } pushDown( rt ); int mid = ( l + r ) / 2; int ls = 2 * rt; int rs = ls | 1; if( mid >= aa ) query( l, mid, ls, aa, bb ); if( mid < bb ) query( mid + 1, r, rs, aa, bb ); } void update( int l, int r, int rt, int aa, int bb, int opn, int f ) { if( aa <= l && r <= bb ) { switch( f ) { case 0: OR( rt, opn ); break; case 1: ADD( rt, opn ); break; case 2: XOR( rt, opn ); break; } return; } pushDown( rt ); int mid = ( l + r ) / 2; int ls = 2 * rt; int rs = ls | 1; if( mid >= aa ) update( l, mid, ls, aa, bb, opn, f ); if( mid < bb ) update( mid + 1, r, rs, aa, bb, opn, f ); pushUp( rt ); } int main() { int t, n, m, aa, bb, opn; char cmd[4]; scanf("%d", &t); while( t-- ) { memset( flag, -1, sizeof(flag) ); scanf("%d%d", &n, &m); build(0, n-1, 1); while( m-- ) { scanf("%s", cmd); if( cmd[0] == 'S' ) { scanf("%d%d", &aa, &bb); res = 0; query( 0, n - 1, 1, aa, bb ); printf("%d ", res); } else { scanf("%d%d%d", &opn, &aa, &bb); switch( cmd[0] ) { case 'O': update(0, n-1, 1, aa, bb, opn, 0); break; case 'A': update(0, n-1, 1, aa, bb, opn, 1); break; case 'X': update(0, n-1, 1, aa, bb, opn, 2); break; default : break; } } } } return 0; }
  • 相关阅读:
    java实现Floyd算法
    java实现Floyd算法
    java实现Floyd算法
    java实现Floyd算法
    java实现Dijkstra算法
    java实现Dijkstra算法
    java实现Dijkstra算法
    java实现Dijkstra算法
    java实现Dijkstra算法
    QTableWidget简单应用之文件浏览器
  • 原文地址:https://www.cnblogs.com/yaling/p/3379426.html
Copyright © 2011-2022 走看看