您的位置:首页 > 其它

codevs 1690 线段树

2015-08-28 09:57 302 查看
“反转类问题”需要注意的是pushdown懒标记的时候要用异或(或者++%2)而不是赋值,因为它是和奇偶性有关系的。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 100001;

struct Node
{
int l, r, sum, rev;
} node[N << 2];

void pushup( int i )
{
node[i].sum = node[i << 1].sum + node[i << 1 | 1].sum;
}

void build( int i, int l, int r )
{
node[i].l = l, node[i].r = r, node[i].rev = node[i].sum = 0;
if ( l == r ) return ;
int mid = ( l + r ) >> 1;
build( i << 1, l, mid );
build( i << 1 | 1, mid + 1, r );
}

void pushdown( int i )
{
if ( node[i].rev )
{
int lc = i << 1, rc = lc | 1;
node[lc].rev ^= 1;
node[rc].rev ^= 1;
node[lc].sum = node[lc].r - node[lc].l + 1 - node[lc].sum;
node[rc].sum = node[rc].r - node[rc].l + 1 - node[rc].sum;
node[i].rev = 0;
}
}

void update( int i, int l, int r )
{
if ( node[i].l == l && node[i].r == r )
{
node[i].sum = node[i].r - node[i].l + 1 - node[i].sum;
node[i].rev ^= 1;
return ;
}
pushdown(i);
int mid = ( node[i].l + node[i].r ) >> 1;
if ( r <= mid )
{
update( i << 1, l, r );
}
else if ( l > mid )
{
update( i << 1 | 1, l, r );
}
else
{
update( i << 1, l, mid );
update( i << 1 | 1, mid + 1, r );
}
pushup(i);
}

int query( int i, int l, int r )
{
if ( node[i].l == l && node[i].r == r )
{
return node[i].sum;
}
pushdown(i);
int mid = ( node[i].l + node[i].r ) >> 1;
if ( r <= mid )
{
return query( i << 1, l, r );
}
else if ( l > mid )
{
return query( i << 1 | 1, l, r );
}
else
{
return query( i << 1, l, mid ) + query( i << 1 | 1, mid + 1, r );
}
}

int main ()
{
int n, m;
while ( scanf("%d%d", &n, &m) != EOF )
{
build( 1, 1, n );
while ( m-- )
{
int op, x, y;
scanf("%d%d%d", &op, &x, &y);
if ( op == 0 )
{
update( 1, x, y );
}
else
{
printf("%d\n", query( 1, x, y ));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: