您的位置:首页 > 产品设计 > UI/UE

线段树 HDU 3397 Sequence operation

2012-08-30 21:43 363 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397

代码风格:http://www.notonlysuccess.com/index.php/segment-tree-complete/

题目大意:操作说明:0——把[a,b]区间全部变成0;1——把[a, b]区间全部变成1;2——把[a,b]区间0,1取反;3——输出[a,b]区间1的个数;4——输出[a, b]区间最长连续1的长度

算法:线段树 区间合并

思路:0,1 操作如果不会可以去做一下POJ3367,代码见http://www.notonlysuccess.com/index.php/segment-tree-complete/

同时统计0和1的左边连续个数lsun,lsum,右边连续个数rsun,rsum,区间最长连续个数msun,msum以及区间内1的个数p

0,1操作时,把取反标记清零

2操作:建立数组x[]作为取反标记,并且lsum,rsun互换,rsum,rsun互换,msum, msun互换,p改变

#include"cstdio"
#include"cstring"
#include"cmath"
#include"algorithm"
using namespace std;

const int Max = 444444;
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1 | 1
#define mid int m  = (l+r) >> 1

int lsun[Max], rsun[Max], msun[Max];
int rsum[Max], lsum[Max], msum[Max];
int cover[Max], p[Max], x[Max];

void fxor(int rt)
{
if(cover[rt] != -1)
cover[rt] ^= 1;
else x[rt] ^= 1;
}

int max(int a, int b)
{
return a > b ? a : b;
}

int min(int a, int b)
{
return a < b ? a : b;
}

void PushUp(int l, int r, int rt, int m)
{
//printf("%d -- %d, rt == %d\n", p[rt << 1 ], p[rt << 1 | 1], rt);
p[rt] = p[rt << 1 ] + p[rt << 1 | 1];
rsum[rt] = rsum[rt << 1 | 1];
rsun[rt] = rsun[rt << 1 | 1];
lsum[rt] = lsum[rt << 1];
lsun[rt] = lsun[rt << 1];
if(lsun[rt] == m - (m >> 1))
lsun[rt] += lsun[rt << 1 | 1];
if(lsum[rt] == m - (m >> 1))
lsum[rt] += lsum[rt << 1 | 1];
if(rsun[rt] == m >> 1)
rsun[rt] += rsun[rt << 1];
if(rsum[rt] == m >> 1)
rsum[rt] += rsum[rt << 1];
msum[rt] = max(max(msum[rt << 1], msum[rt << 1 | 1]), lsum[rt << 1 | 1] + rsum[rt << 1]);
msun[rt] = max(max(msun[rt << 1], msun[rt << 1 | 1]), lsun[rt << 1 | 1] + rsun[rt << 1 ]);
}

void PushDown(int rt, int m)
{
if(cover[rt] != -1)
{
cover[rt << 1] = cover[rt << 1 | 1] = cover[rt];
msum[rt << 1] = rsum[rt << 1] = lsum[rt << 1] = p[rt << 1] = cover[rt] * (m - (m >> 1));
msum[rt << 1 | 1] = rsum[rt << 1 | 1] = lsum[rt << 1 | 1] = p[rt << 1 | 1] = cover[rt] * (m >> 1);
msun[rt << 1] = rsun[rt << 1] = lsun[rt << 1] = cover[rt] ? 0 : m - (m >> 1);
msun[rt << 1 | 1] = rsun[rt << 1 | 1] = lsun[rt << 1 | 1] = cover[rt] ?0 : m >> 1;
x[rt << 1] = x[rt << 1 | 1] = 0;
cover[rt] = -1;
}
if(x[rt] != 0)
{
fxor(rt << 1);
fxor(rt << 1 | 1);
p[rt << 1] = (m - (m >> 1)) - p[rt << 1];
p[rt << 1 | 1] = (m >> 1) - p[rt << 1 | 1];
int k = lsum[rt << 1]; lsum[rt << 1] = lsun[rt << 1]; lsun[rt << 1] = k;
k = rsum[rt << 1]; rsum[rt << 1] = rsun[rt << 1]; rsun[rt << 1] = k;
k = msum[rt << 1]; msum[rt << 1] = msun[rt << 1]; msun[rt << 1] = k;
k = lsum[rt << 1 | 1]; lsum[rt << 1 | 1] = lsun[rt << 1 | 1]; lsun[rt << 1 | 1] = k;
k = rsum[rt << 1 | 1]; rsum[rt << 1 | 1] = rsun[rt << 1 | 1]; rsun[rt << 1 | 1] = k;
k = msum[rt << 1 | 1]; msum[rt << 1 | 1] = msun[rt << 1 | 1]; msun[rt << 1 | 1] = k;
x[rt] = 0;
}
}

void build(int l, int r, int rt)
{
if(l == r)
{
scanf("%d", &p[rt]);
rsum[rt] = msum[rt] = lsum[rt] = p[rt] ? 1 : 0;
rsun[rt] = msun[rt] = lsun[rt] = p[rt] ? 0 : 1;
//printf("msum[rt] = %d\n", msum[rt]);
return ;
}
mid ;
build(lson);
build(rson);
PushUp(m, m+1, rt, r-l+1);
}

void update(int op, int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R)
{
if(op == 2)
{
p[rt] = r-l+1-p[rt];
int k = lsum[rt]; lsum[rt] = lsun[rt]; lsun[rt] = k;
k = rsum[rt]; rsum[rt] = rsun[rt]; rsun[rt] = k;
k = msum[rt]; msum[rt] = msun[rt]; msun[rt] = k;
fxor(rt);
}
else
{
cover[rt] = op;
lsum[rt] = msum[rt] = rsum[rt] = p[rt] = op ? r-l+1 : 0;
lsun[rt] = msun[rt] = rsun[rt] = op ? 0 : r-l+1;
x[rt] = 0;
}
return ;
}
mid ;
PushDown(rt, r-l+1);
if(L <= m)
update(op, L, R, lson);
if(m < R)
update(op, L, R, rson);
PushUp(m, m+1, rt, r-l+1);
}

int query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R)
{
return p[rt];
}
int ret = 0;
PushDown(rt, r-l+1);
mid;
if(L <= m)
ret += query(L, R, lson);
if(m < R)
ret += query(L, R, rson);
return ret ;
}

int Query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R)
{
return msum[rt];
}
mid;
PushDown(rt, r-l+1);
if(m < L)
return Query(L, R, rson);
else if(R <= m)
return Query(L, R, lson);
return max(max(min(rsum[rt << 1], m+1-L) + min(lsum[rt << 1 | 1], R-m), Query(L, R, lson)), Query(L, R, rson) );
}

int main()
{
int T, n, m;
scanf("%d", &T);
while( T --)
{
memset(x, 0, sizeof(x));
memset(cover, -1, sizeof(cover));
scanf("%d%d", &n, &m);
build(0, n-1, 1);

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