bzoj 1858

这个线段树要维护的东西挺多。。。连样例都不敢拿来调。。只好自己出更弱的数据0.0

  1 #include<bits/stdc++.h>
  2 #define inc(i,l,r) for(i=l;i<=r;i++)
  3 #define dec(i,l,r) for(i=1;i>=r;i--)
  4 #define inf 1e9
  5 #define mem(a) memset(a,0,sizeof(a))
  6 #define NM 100000+5
  7 using namespace std;
  8 int n,m,i,t,x,y;
  9 struct info{
 10     int s,l,r,m,z,w,x,y,n;
 11     info(int t=0){
 12         z=-1;
 13         l=r=s=m=t;
 14         x=y=w=n=t^1;
 15     }
 16 }T[3*NM],none;
 17 info operator+(const info&x,const info&y){
 18     info f;
 19     f.z-1;
 20     if(x.w==0)f.l=x.s+y.l;else f.l=x.l;
 21     if(y.w==0)f.r=y.s+x.r;else f.r=y.r;
 22     f.s=x.s+y.s;
 23     f.m=max(x.m,y.m);
 24     f.m=max(f.m,x.r+y.l);
 25     if(x.s==0)f.x=x.w+y.x;else f.x=x.x;
 26     if(y.s==0)f.y=y.w+x.y;else f.y=y.y;
 27     f.w=x.w+y.w;
 28     f.n=max(x.n,y.n);
 29     f.n=max(f.n,x.y+y.x);
 30     return f;
 31 }
 32 void mark(int i){
 33     if(T[i].z==2)T[i].z=-1;
 34     else if(T[i].z==-1)T[i].z=2;
 35     else T[i].z^=1;
 36 }
 37 void pushdown(int i){
 38     info *t=&T[i];
 39     if(t->z==2){
 40         swap(t->l,t->x);swap(t->r,t->y);swap(t->s,t->w);swap(t->m,t->n);
 41         mark(i*2);mark(i*2+1);
 42     }else if(t->z==1){
 43         t->l=t->r=t->m=t->s=t->s+t->w;
 44         t->w=t->n=t->x=t->y=0;
 45         T[i*2].z=T[i*2+1].z=1;
 46     }else if(t->z==0){
 47         t->w=t->n=t->x=t->y=t->s+t->w;
 48         t->l=t->r=t->m=t->s=0;
 49         T[i*2].z=T[i*2+1].z=0;
 50     }
 51     t->z=-1;
 52 }
 53 void build(int i,int x,int y){
 54     int t=(x+y)>>1;
 55     if(x==y){
 56         scanf("%d",&x);
 57         T[i]=info(x);
 58         return;
 59     }
 60     build(i*2,x,t);build(i*2+1,t+1,y);
 61     T[i]=T[i*2]+T[i*2+1];
 62 }
 63 void deal(int i,int x,int y,int a,int b,int k){
 64     int t=(x+y)>>1;
 65     pushdown(i);
 66     if(b<x||y<a)return;
 67     if(a<=x&&y<=b){
 68         T[i].z=k;
 69         pushdown(i);
 70         return;
 71     }
 72     deal(i*2,x,t,a,b,k);deal(i*2+1,t+1,y,a,b,k);
 73     T[i]=T[i*2]+T[i*2+1];
 74 }
 75 void ch(int i,int x,int y,int a,int b){
 76     int t=(x+y)>>1;
 77     pushdown(i);
 78     if(b<x||y<a)return;
 79     if(a<=x&&y<=b){
 80         mark(i);
 81         pushdown(i);
 82         return;
 83     }
 84     ch(i*2,x,t,a,b);ch(i*2+1,t+1,y,a,b);
 85     T[i]=T[i*2]+T[i*2+1];
 86 }
 87 int sum(int i,int x,int y,int a,int b){
 88     int t=(x+y)>>1;
 89     if(b<x||a>y)return 0;
 90     pushdown(i);
 91     if(a<=x&&y<=b)return T[i].s;
 92     return sum(i*2,x,t,a,b)+sum(i*2+1,t+1,y,a,b);
 93 }
 94 info link(int i,int x,int y,int a,int b){
 95     int t=(x+y)>>1;
 96     if(b<x||y<a)return none;
 97     pushdown(i);
 98     if(a<=x&&y<=b)return T[i];
 99     return link(i*2,x,t,a,b)+link(i*2+1,t+1,y,a,b);
100 }
101 int main(){
102     none=info(0);
103     scanf("%d%d",&n,&m);
104     build(1,1,n);
105     inc(i,1,m){
106         scanf("%d%d%d",&t,&x,&y);
107         x++;y++;
108         if(t==0||t==1)deal(1,1,n,x,y,t);
109         else if(t==2)ch(1,1,n,x,y);
110         else if(t==3)printf("%d\n",sum(1,1,n,x,y));
111         else if(t==4)printf("%d\n",link(1,1,n,x,y).m);
112     }
113     return 0;
114 }

时间: 2024-10-28 14:24:05

bzoj 1858的相关文章

bzoj 1858: [Scoi2010] 序列操作 题解

[原题] 1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 1031  Solved: 529 [Submit][Status] Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内

AC日记——[Scoi2010]序列操作 bzoj 1858

1858 思路: 恶心: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 struct TreeNodeType { int l,r,l1,r1,m1,l0,r0,m0,mid,size,cnt1,cnt0; bool f1,f0,ff; inline void turn(){swap(l1,l0),swap(r1,r0),swap(m1,m0),swap(cnt1,cnt0);} inline voi

【BZOJ 1858】 [Scoi2010]序列操作

1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1368 Solved: 712 [Submit][Status][Discuss] Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区

bzoj 1858: [Scoi2010]序列操作

1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右中的1和0连续个数,并在op=4时特殊处理一下. Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内的所有数全

bzoj 1858 序列操作(线段树)

题外话 本来想练练线段树的,然后发现这题及其蛋疼,要打一坨标记,这是我写过的最长的线段树了= = 然后我很SB的把R打成了r调了一个下午真是蛋疼QvQ Description: 给定一个0/1序列,有如下5个操作: 0:区间赋值为0 1:区间赋值为1 2:区间取反 3:询问区间内1的个数 4:询问区间内最大连续1的个数 Solution 没有操作4这显然就是个SB题,有了操作4我们需要打几个标记 我们需要从左端点开始连续0/1的个数,从右端点开始的连续0/1个数 区间内0/1个数,区间内最大连续

BZOJ 1858 SCOI2010 序列操作 线段树

题目大意:给定一个01序列,提供三种操作: 0:把一段区间的全部元素都变成0 1:把一段区间的全部元素都变成1 2:把一段区间内的全部元素全都取反 3:查询一段区间内1的个数 4:查询一段区间内最长的一段连续的1 首先假设没有操作4这就是bitset的水题... 多了这个,我们考虑线段树 线段树的每个节点存改动标记和翻转标记,以及该区间的信息 尽管查询的信息都是1 可是我们要连0一起保存 由于翻转后0就变成了1 1就变成了0 区间信息包含: 左端点的元素 右端点的元素 左端点開始的最长的连续元素

序列操作(bzoj 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都需要给出回答,聪

BZOJ 1858 SCOI 2010 序列操作

题目大意:维护一种01数据结构,它可以: 1.把一段区间变成0. 2.把一段区间变成1. 3.把一段区间取反. 4.查询一段区间内1的个数. 5.查询一段区间内连续的1的个数. 思路:一眼看去Splay和线段树都可以,看起来好像Splay维护起来好弄一点,就没怎么想写了Splay.写完之后才发现Splay维护的时候边界值根本没法弄(可能是我写的麻烦),就又重写线段树.啊啊啊啊现在整个人都发要疯了.. 其实线段树和Splay的思想是一样的,需要维护一下几个东西: 1.一段区间内,左边开始连续0的个

bzoj 1858: [Scoi2010]序列操作 || 洛谷 P2572

记一下:线段树占空间是$2^{ceil(log2(n))+1}$ 这个就是一个线段树区间操作题,各种标记的设置.转移都很明确,只要熟悉这类题应该说是没有什么难度的. 由于对某区间set之后该区间原先待进行的取反操作失效(被覆盖),因此规定tag同时存在时set的标记先进行操作,这样对区间加上set标记时要去掉原有的取反标记. 对于操作4,线段树上每个区间维护6个值,分别表示:该区间最多的连续0/1,从左侧数起/从右侧数起/其中任意位置.题目中不问连续0,为什么连续0也要维护呢?这是为了在进行取反