九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/12223079
题意:
t个测试数据
n 个数 m个操作
下面n个数的当前颜色(只有 0 1 两种 )
oper [u,v]
oper==0 区间染0色
oper==1 区间染1色
oper==2 区间反色
oper==3 问区间1色个数
oper==4 问区间 连续1色个数
代码写搓了:
#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<set>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <math.h>
#include <queue>
#define N 1001000
#define ll int
#define L(x) x<<1
#define R(x) x<<1|1
#define Mid(x,y) (x+y)>>1
using namespace std;
inline ll Min(ll a,ll b){return a>b?b:a;}
inline ll Max(ll a,ll b){return a>b?a:b;}
int a[N];//1是黑
struct node{
int l,r;
int Win, Bin;//区间内黑白的最长
int Llen, Rlen;// Llen 是 这个区间内 从区间左端点向右连续相同颜色的长度
int Lc, Rc;//左端颜色
int lazy;
int len(){return r-l+1;}
int onenum;
}tree[N];
void change_other(int id,int oper){
tree[id].Llen = tree[id].Rlen = tree[id].len();
if(oper == 1)//全改0
{
tree[id].Bin = tree[id].Lc = tree[id].Rc = 0;
tree[id].Win = tree[id].len();
tree[id].onenum = 0;
}
if(oper == 2)//全改1
{
tree[id].Lc = tree[id].Rc = 1;
tree[id].onenum = tree[id].Bin = tree[id].len();
tree[id].Win = 0;
}
tree[id].lazy = 0;
tree[L(id)].lazy = tree[R(id)].lazy = oper;
}
void Lazy(int id){
if(!tree[id].lazy)
return ;
if(tree[id].lazy == 3)
{
tree[id].Lc ^= 1;
tree[id].Rc ^= 1;
int temp = tree[id].Win; tree[id].Win = tree[id].Bin; tree[id].Bin = temp;
tree[id].onenum = tree[id].len() - tree[id].onenum;
if(tree[L(id)].lazy == 3) tree[L(id)].lazy = 0;
else { Lazy(L(id)); tree[L(id)].lazy =3; }
if(tree[R(id)].lazy == 3) tree[R(id)].lazy = 0;
else { Lazy(R(id)); tree[R(id)].lazy =3; }
}
if(tree[id].lazy == 1){
tree[id].Bin = tree[id].Lc = tree[id].Rc = 0;
tree[id].Win = tree[id].Llen = tree[id].Rlen = tree[id].len();
tree[id].onenum = 0;
tree[L(id)].lazy = tree[R(id)].lazy = 1;
}
if(tree[id].lazy == 2){
tree[id].Lc = tree[id].Rc = 1;
tree[id].onenum = tree[id].Bin = tree[id].Llen = tree[id].Rlen = tree[id].len();
tree[id].Win = 0;
tree[L(id)].lazy = tree[R(id)].lazy = 2;
}
tree[id].lazy = 0;
}
void change(int id){
tree[id].Lc ^= 1;
tree[id].Rc ^= 1;
int temp = tree[id].Win; tree[id].Win = tree[id].Bin; tree[id].Bin = temp;
tree[id].onenum = tree[id].len() - tree[id].onenum;
if(tree[L(id)].lazy == 3)tree[L(id)].lazy = 0;
else {Lazy(L(id)); tree[L(id)].lazy = 3;}
if(tree[R(id)].lazy == 3)tree[R(id)].lazy = 0;
else {Lazy(R(id)); tree[R(id)].lazy = 3;}
}
void updata_up(int id){
if(tree[id].l == tree[id].r) return ;
Lazy(L(id)), Lazy(R(id));
tree[id].Lc = tree[L(id)].Lc , tree[id].Rc = tree[R(id)].Rc ;
tree[id].Rlen = tree[R(id)].Rlen;
tree[id].Llen = tree[L(id)].Llen;
tree[id].Bin=Max(tree[L(id)].Bin, tree[R(id)].Bin);
tree[id].Win=Max(tree[L(id)].Win, tree[R(id)].Win);
if( tree[L(id)].Rc == tree[R(id)].Lc)
{
if(tree[L(id)].Rc)
tree[id].Bin = Max(tree[id].Bin, tree[L(id)].Rlen + tree[R(id)].Llen);
else
tree[id].Win = Max(tree[id].Win, tree[L(id)].Rlen + tree[R(id)].Llen);
if(tree[L(id)].Llen == tree[L(id)].len())
tree[id].Llen = tree[L(id)].len() + tree[R(id)].Llen;
if(tree[R(id)].Rlen == tree[R(id)].len())
tree[id].Rlen = tree[R(id)].len() + tree[L(id)].Rlen;
}
if(tree[id].Lc==1)tree[id].Bin=Max(tree[id].Bin, tree[id].Llen);
else tree[id].Win=Max(tree[id].Win, tree[id].Llen);
if(tree[id].Rc==1)tree[id].Bin=Max(tree[id].Bin, tree[id].Rlen);
else tree[id].Win=Max(tree[id].Win, tree[id].Rlen);
tree[id].onenum = tree[L(id)].onenum + tree[R(id)].onenum;
}
void build(int l,int r,int id){
tree[id].l = l, tree[id].r = r;
tree[id].lazy=0;
if(l == r){
tree[id].Llen=tree[id].Rlen=1;
tree[id].Lc = tree[id].Rc = a[l];
tree[id].Bin = a[l];
tree[id].Win = 1-a[l];
tree[id].onenum = a[l];
return ;
}
int mid = Mid(l,r);
build( l, mid, L(id));
build( mid+1, r, R(id));
updata_up(id);
}
void updata(int l, int r, int id){
Lazy(id);
if(l == tree[id].l && tree[id].r == r)
{ change(id); return ;}
int mid=Mid(tree[id].l, tree[id].r);
if(r <= mid) updata(l, r, L(id));
else if(mid < l) updata(l, r, R(id));
else {
updata(l, mid, L(id));
updata(mid+1, r, R(id));
}
updata_up(id);
}
void updata_other(int l, int r, int id,int oper){
Lazy(id);
if(l == tree[id].l && tree[id].r == r)
{change_other(id,oper); return ;}
int mid=Mid(tree[id].l, tree[id].r);
if(r <= mid) updata_other(l, r, L(id),oper);
else if(mid < l) updata_other(l, r, R(id),oper);
else {
updata_other(l, mid, L(id),oper);
updata_other(mid+1, r, R(id),oper);
}
updata_up(id);
}
int query(int l, int r, int id){
Lazy(id);
if(l == tree[id].l && tree[id].r == r)
return tree[id].Bin;
int mid=Mid(tree[id].l, tree[id].r);
int r1=0, r2=0, ans=0;
if(r <= mid) r1 = query(l, r, L(id));
else if(mid < l) r2 = query(l, r, R(id));
else {
r1 = query(l, mid, L(id));
r2 = query(mid+1, r, R(id));
if(tree[L(id)].Rc == 1 && tree[R(id)].Lc == 1)
ans = Min(mid-l+1, tree[L(id)].Rlen) + Min(r-mid, tree[R(id)].Llen) ;
r1 = Max(ans, r1);
}
ans = Max(r1, r2);
return ans;
}
int query_one(int l, int r, int id){
Lazy(id);
if(l == tree[id].l && tree[id].r == r)
return tree[id].onenum;
int mid=Mid(tree[id].l, tree[id].r);
int r1=0, r2=0;
if(r <= mid) r1 = query_one(l, r, L(id));
else if(mid < l) r2 = query_one(l, r, R(id));
else {
r1 = query_one(l, mid, L(id));
r2 = query_one(mid+1, r, R(id));
}
return r1+r2;
}
int main(){
int n, que, oper, b, c,T;scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&que);
for(int i=1;i<=n;i++)scanf("%d", &a[i]);
build(1,n,1);
while(que--)
{
scanf("%d %d %d", &oper, &b, &c);
oper++,b++,c++;
if(oper==3)
updata(b,c,1);
else if(oper<=2)
updata_other(b,c,1,oper);
else
{
if(oper==4)
printf("%d\n",query_one(b,c,1));
if(oper==5)
printf("%d\n", query(b,c,1));//问黑色
}
}
}
return 0;
}
/*
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
0 0 0 1 1 0 1 0 1 1
1 1 1 1 1 0 1 0 1 1 1 3 改1
1 1 0 1 1 0 1 0 1 1 3 3 换
1 1 0 0 0 0 0 0 1 1 4 7 改0
1 1 0 1 1 1 1 1 1 1 4 8 换 there
1 1 1 1 1 1 1 1 1 1 1 6 改1
1 1 1 1 1 0 0 1 1 1 6 7 改0
*/