HDU 3397 线段树区间染色 区间查询

来源:互联网 发布:淘宝微商代理能挣钱吗? 编辑:程序博客网 时间:2024/06/05 00:50

九野的博客,转载请注明出处: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;  }  /*110 100 0 0 1 1 0 1 0 1 11 0 23 0 52 2 24 0 40 3 62 3 74 2 81 0 50 5 63 3 90 0 0 1 1 0 1 0 1 11 1 1 1 1 0 1 0 1 1  1 3  改11 1 0 1 1 0 1 0 1 1  3 3  换1 1 0 0 0 0 0 0 1 1  4 7  改01 1 0 1 1 1 1 1 1 1  4 8  换  there1 1 1 1 1 1 1 1 1 1  1 6  改11 1 1 1 1 0 0 1 1 1  6 7  改0*/

原创粉丝点击