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

HDOJ 题目3397 Sequence operation(线段树区间覆盖异或合并)

2015-09-02 00:30 405 查看

Sequence operation

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 7203 Accepted Submission(s): 2153



[align=left]Problem Description[/align]
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]

[align=left]Input[/align]
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.

[align=left]Output[/align]
For each output operation , output the result.

[align=left]Sample Input[/align]

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


[align=left]Sample Output[/align]

5
2
6
5


[align=left]Author[/align]
lxhgww&&shǎ崽

[align=left]Source[/align]
HDOJ Monthly Contest – 2010.05.01

[align=left]Recommend[/align]
lcy | We have carefully selected several similar problems for you: 1828 1542 2871 1255 3333
这么多操作结合起来真是恶心啊,0把区间赋值0,1把区间都赋值成1,2区间异或,3查询区间1的个数,4查询区间连续的1的长度
为何我是如此的弱啊




ac代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a>b?b:a)
using namespace std;
#define maxn 100010
struct s
{
int ml0,mr0,mx0;
int ml1,mr1,mx1;
int sum;
int cover,Xor;
}node[maxn<<2];
void pushup(int tr,int m)
{
node.ml0=node[tr<<1].ml0;
node.ml1=node[tr<<1].ml1;

node.mr0=node[tr<<1|1].mr0;
node.mr1=node[tr<<1|1].mr1;

if(node[tr<<1].ml0==(m-(m>>1)))
node.ml0+=node[tr<<1|1].ml0;
if(node[tr<<1|1].mr0==(m>>1))
node.mr0+=node[tr<<1].mr0;
node.mx0=max(node[tr<<1].mx0,node[tr<<1|1].mx0);
node.mx0=max(node.mx0,node[tr<<1].mr0+node[tr<<1|1].ml0);

if(node[tr<<1].ml1==(m-(m>>1)))
node.ml1+=node[tr<<1|1].ml1;
if(node[tr<<1|1].mr1==(m>>1))
node.mr1+=node[tr<<1].mr1;
node.mx1=max(node[tr<<1].mx1,node[tr<<1|1].mx1);
node.mx1=max(node.mx1,node[tr<<1].mr1+node[tr<<1|1].ml1);

node.sum=node[tr<<1].sum+node[tr<<1|1].sum;
}
void fxor(int tr,int m)
{
swap(node.ml0,node.ml1);
swap(node.mr0,node.mr1);
swap(node.mx0,node.mx1);
node.sum=m-node.sum;
}
void build(int l,int r,int tr)
{
node.cover=-1;
node.Xor=0;
if(l==r)
{
int x;
scanf("%d",&x);
node.ml0=node.mr0=node.mx0=(x==0);
node.ml1=node.mr1=node.mx1=(x==1);
node.cover=x;
node.sum=x;
return;
}
int mid=(l+r)>>1;
build(l,mid,tr<<1);
build(mid+1,r,tr<<1|1);
pushup(tr,r-l+1);
}
void pushdown(int tr,int m)
{
if(m==1)
return;
if(node.cover!=-1)
{
node[tr<<1].cover=node[tr<<1|1].cover=node.cover;
node[tr<<1].Xor=node[tr<<1|1].Xor=0;

if(node.cover)
{
node[tr<<1].ml1=node[tr<<1].mr1=node[tr<<1].mx1=(m-(m>>1));
node[tr<<1].ml0=node[tr<<1].mr0=node[tr<<1].mx0=0;
node[tr<<1].sum=(m-(m>>1));

node[tr<<1|1].ml1=node[tr<<1|1].mr1=node[tr<<1|1].mx1=(m>>1);
node[tr<<1|1].ml0=node[tr<<1|1].mr0=node[tr<<1|1].mx0=0;
node[tr<<1|1].sum=(m>>1);
}
else
{
node[tr<<1].ml1=node[tr<<1].mr1=node[tr<<1].mx1=0;
node[tr<<1].ml0=node[tr<<1].mr0=node[tr<<1].mx0=(m-(m>>1));
node[tr<<1].sum=0;

node[tr<<1|1].ml1=node[tr<<1|1].mr1=node[tr<<1|1].mx1=0;
node[tr<<1|1].ml0=node[tr<<1|1].mr0=node[tr<<1|1].mx0=(m>>1);
node[tr<<1|1].sum=0;
}

node.cover=-1;
}
if(node.Xor)
{
node[tr<<1].Xor^=1;
node[tr<<1|1].Xor^=1;
fxor(tr<<1,m-(m>>1));
fxor(tr<<1|1,m>>1);
node.Xor=0;
}
}
void update(int L,int R,int l,int r,int tr,int op)
{
pushdown(tr,r-l+1);//先向下跟新啊。。
if(L<=l&&r<=R)
{
if(op==2)
{
node.Xor=1;
fxor(tr,r-l+1);
}
else
{
int m=(r-l)+1;
node.cover=op;
if(op)
{
node.ml1=node.mr1=node.mx1=m;
node.ml0=node.mr0=node.mx0=0;
node.sum=m;
}
else
{
node.ml1=node.mr1=node.mx1=0;
node.ml0=node.mr0=node.mx0=m;
node.sum=0;
}
}
return;
}
int mid=(l+r)>>1;
if(L<=mid)
update(L,R,l,mid,tr<<1,op);
if(R>mid)
update(L,R,mid+1,r,tr<<1|1,op);
pushup(tr,r-l+1);
}
int query_sum(int L,int R,int l,int r,int tr)
{
if(L<=l&&r<=R)
{
return node.sum;
}
pushdown(tr,r-l+1);
int mid=(l+r)>>1;
int ans1=0;
int ans2=0;
if(L<=mid)
ans1=query_sum(L,R,l,mid,tr<<1);
if(R>mid)
ans2=query_sum(L,R,mid+1,r,tr<<1|1);
//    pushup(tr,r-l+1);
return ans1+ans2;
}
int query_max1(int L,int R,int l,int r,int tr)
{
if(L<=l&&r<=R)
{
return node.mx1;
}
pushdown(tr,r-l+1);
int mid=(l+r)>>1;
int ans=0;
if(R<=mid)
ans=query_max1(L,R,l,mid,tr<<1);
else
if(L>mid)
ans=query_max1(L,R,mid+1,r,tr<<1|1);
else
{
int ans1=query_max1(L,mid,l,mid,tr<<1);
int ans2=query_max1(mid+1,R,mid+1,r,tr<<1|1);
int ans3=min(node[tr<<1].mr1,mid-L+1)+min(node[tr<<1|1].ml1,R-(mid+1)+1);
ans=max(ans1,max(ans2,ans3));
}
//    pushup(tr,r-l+1);
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
x++;
y++;
if(op<3)
update(x,y,1,n,1,op);
else
{
if(op==3)
{
printf("%d\n",query_sum(x,y,1,n,1));
}
else
{
printf("%d\n",query_max1(x,y,1,n,1));
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: