九野的博客,转载请注明出处: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 */