传送门:
http://www.lydsy.com/JudgeOnline/problem.php?id=1858
Description
lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0 3 a b 询问[a, b]区间内总共有多少个1 4 a b 询问[a, b]区间内最多有多少个连续的1 对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,你们能帮助他吗?
Input
输入数据第一行包括2个数,n和m,分别表示序列的长度和操作数目 第二行包括n个数,表示序列的初始状态 接下来m行,每行3个数,op, a, b,(0<=op<=4,0<=a<=b<n)表示对于区间[a, b]执行标号为op的操作="" <="" div="" style="font-family: arial, verdana, helvetica, sans-serif;">
Output
对于每一个询问操作,输出一行,包括1个数,表示其对应的答案
Sample Input
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
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
2
6
5
HINT
对于30%的数据,1<=n, m<=1000
对于100%的数据,1<=n, m<=100000
不错的线段树模板题
马丹,因为多打了个等号调了半个小时~~~~~省选可不要犯这种低级错误啊啊啊啊!!!!
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
#include<iostream>
#define MAXN 100010
using namespace std;
struct segment
{
int from,to,l1,l0,r1,r0,m1,m0,sum,lazy;
} s[MAXN*4];
int oper,a[MAXN];
void update(int p)
{
int l=p<<1,r=l+1;
if(s[l].to-s[l].from==s[l].l1)
s[p].l1=s[l].l1+s[r].l1;
else
s[p].l1=s[l].l1;
if(s[r].to-s[r].from==s[r].r1)
s[p].r1=s[r].r1+s[l].r1;
else
s[p].r1=s[r].r1;
if(s[l].to-s[l].from==s[l].l0)
s[p].l0=s[l].l0+s[r].l0;
else
s[p].l0=s[l].l0;
if(s[r].to-s[r].from==s[r].r0)
s[p].r0=s[r].r0+s[l].r0;
else
s[p].r0=s[r].r0;
s[p].m1=max(s[l].r1+s[r].l1,max(s[l].m1,s[r].m1));
s[p].m0=max(s[l].r0+s[r].l0,max(s[l].m0,s[r].m0));
s[p].sum=s[l].sum+s[r].sum;
}
void push_down(int p)
{
if(s[p].from+1==s[p].to) return;
int l=p<<1,r=(p<<1)+1;
if(s[p].lazy==3&&s[l].lazy) push_down(l);
if(s[p].lazy==3&&s[r].lazy) push_down(r);
s[l].lazy=s[r].lazy=s[p].lazy;
if(s[p].lazy==1)
{
s[l].l0=s[l].r0=s[l].m0=s[l].to-s[l].from;
s[l].l1=s[l].r1=s[l].m1=s[l].sum=0;
s[r].l0=s[r].r0=s[r].m0=s[r].to-s[r].from;
s[r].l1=s[r].r1=s[r].m1=s[r].sum=0;
}
else if(s[p].lazy==2)
{
s[l].l1=s[l].r1=s[l].m1=s[l].sum=s[l].to-s[l].from;
s[l].r0=s[l].l0=s[l].m0=0;
s[r].l1=s[r].r1=s[r].m1=s[r].sum=s[r].to-s[r].from;
s[r].r0=s[r].l0=s[r].m0=0;
}
else
{
swap(s[l].r0,s[l].r1);
swap(s[l].l0,s[l].l1);
swap(s[l].m0,s[l].m1);
s[l].sum=s[l].to-s[l].from-s[l].sum;
swap(s[r].r0,s[r].r1);
swap(s[r].l0,s[r].l1);
swap(s[r].m0,s[r].m1);
s[r].sum=s[r].to-s[r].from-s[r].sum;
}
s[p].lazy=0;
}
void build(int from,int to,int x)
{
s[x].from=from;
s[x].to=to;
if(from+1==to)
{
if(a[from])
s[x].l1=s[x].r1=s[x].sum=s[x].m1=1;
else
s[x].l0=s[x].r0=s[x].m0=1;
}
else
{
int mid=(from+to)>>1;
build(from,mid,x<<1);
build(mid,to,(x<<1)+1);
update(x);
}
}
void change(int from,int to,int x)
{
if(s[x].lazy)
push_down(x);
if(s[x].from==from&&s[x].to==to)
{
if(oper==3)
{
s[x].sum=to-from-s[x].sum;
swap(s[x].l1,s[x].l0);
swap(s[x].r1,s[x].r0);
swap(s[x].m1,s[x].m0);
s[x].lazy=3;
}
else if(oper==2)
{
s[x].sum=s[x].m1=s[x].l1=s[x].r1=to-from;
s[x].m0=s[x].l0=s[x].r0=0;
s[x].lazy=2;
}
else if(oper==1)
{
s[x].sum=s[x].m1=s[x].l1=s[x].r1=0;
s[x].m0=s[x].l0=s[x].r0=to-from;
s[x].lazy=1;
}
return ;
}
int mid=(s[x].to+s[x].from)>>1;
if(to<=mid)
change(from,to,x<<1);
else if(from>=mid)
change(from,to,(x<<1)+1);
else
{
change(from,mid,x<<1);
change(mid,to,(x<<1)+1);
}
update(x);
}
int query(int from,int to,int p)
{
if(s[p].lazy)
push_down(p);
if(s[p].from==from&&s[p].to==to)
return s[p].sum;
int mid=s[p].from+s[p].to>>1;
if(to<=mid)
return query(from,to,p<<1);
else if(from>=mid)
return query(from,to,(p<<1)+1);
return query(from,mid,p<<1)+query(mid,to,(p<<1)+1);
}
segment query2(int from,int to,int p)
{
if(s[p].lazy)
push_down(p);
if(s[p].from==from&&s[p].to==to)
return s[p];
int mid=s[p].from+s[p].to>>1;
if(to<=mid)
return query2(from,to,p<<1);
else if(from>=mid)
return query2(from,to,(p<<1)+1);
segment temp,temp2,temp3;
temp=query2(from,mid,p<<1);
temp2=query2(mid,to,(p<<1)+1);
if(temp.l1==temp.to-temp.from)
temp3.l1=temp.l1+temp2.l1;
else
temp3.l1=temp.l1;
if(temp2.r1==temp2.to-temp2.from)
temp3.r1=temp2.r1+temp.r1;
else
temp3.r1=temp2.r1;
temp3.m1=max(temp.r1+temp2.l1,max(temp.m1,temp2.m1));
return temp3;
}
int main()
{
int n,q,from,to,o;
cin>>n>>q;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
build(1,n+1,1);
int i;
for(i=1; i<=q; i++)
{
scanf("%d%d%d",&o,&from,&to);
from++,to++;
if(o==0)
{
oper=1;
change(from,to+1,1);
}
else if(o==1)
{
oper=2;
change(from,to+1,1);
}
else if(o==2)
{
oper=3;
change(from,to+1,1);
}
else if(o==3)
printf("%d\n",query(from,to+1,1));
else
printf("%d\n",query2(from,to+1,1).m1);
}
return 0;
}
省选 rp++ bless me~~~~