hdu 3911 Black and White 线段树维护01序列
来源:互联网 发布:mysql建立数据库教程 编辑:程序博客网 时间:2024/05/29 03:07
Black And White
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4996 Accepted Submission(s): 1509
Problem Description
There are a bunch of stones on the beach; Stone color is white or black. Little Sheep has a magic brush, she can change the color of a continuous stone, black to white, white to black. Little Sheep like black very much, so she want to know the longest period of consecutive black stones in a range [i, j].
Input
There are multiple cases, the first line of each case is an integer n(1<= n <= 10^5), followed by n integer 1 or 0(1 indicates black stone and 0 indicates white stone), then is an integer M(1<=M<=10^5) followed by M operations formatted as x i j(x = 0 or 1) , x=1 means change the color of stones in range[i,j], and x=0 means ask the longest period of consecutive black stones in range[i,j]
Output
When x=0 output a number means the longest length of black stones in range [i,j].
Sample Input
4
1 0 1 0
5
0 1 4
1 2 3
0 1 4
1 3 3
0 4 4
Sample Output
1
2
0
题意:给你一些01序列,再给你一些询问。当询问为1的时候,把给定区间内所有的0变为1,1边为0,当询问为0的时候,输出所求区间中最长的连续的1的个数。
用线段树。
维护的东西:左右区间最长的1序列和左右区间最长的0序列。左区间最右端有几个连续的1/0,右区间有几个连续的1/0,以及lazy标记,以及最长的0/1序列的答案。
每次比较左区间最大值和右区间的最大值,以及左区间最右端和右区间最左端的和,最大的作为大区间的答案。
每次lazy标记下传就交换01串的答案就行了。
我果然还是只会线段树的傻逼题。。。
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int N = 1000010;int a[N];inline int Max(int a,int b){ return a>b?a:b;}struct node{ int mmax1,mmax0; int flag; int lm1,rm1;//分别表示左区间最长的1的串和右区间的最长的1的串 int lm0,rm0; int l,r;}tree[N];void pushup(int root){ int llen=tree[root<<1].r-tree[root<<1].l+1; int rlen=tree[root<<1|1].r-tree[root<<1|1].l+1; tree[root].lm1=tree[root<<1].lm1; if(tree[root<<1].lm1==llen) tree[root].lm1+=tree[root<<1|1].lm1; tree[root].rm1=tree[root<<1|1].rm1; if(tree[root<<1|1].rm1==rlen) tree[root].rm1+=tree[root<<1].rm1; int c=Max(tree[root<<1].mmax1,tree[root<<1|1].mmax1); int d=tree[root<<1|1].lm1+tree[root<<1].rm1; tree[root].mmax1=Max(c,d); tree[root].lm0=tree[root<<1].lm0; if(tree[root<<1].lm0==llen) tree[root].lm0+=tree[root<<1|1].lm0; tree[root].rm0=tree[root<<1|1].rm0; if(tree[root<<1|1].rm0==rlen) tree[root].rm0+=tree[root<<1].rm0; c=Max(tree[root<<1].mmax0,tree[root<<1|1].mmax0); d=tree[root<<1|1].lm0+tree[root<<1].rm0; tree[root].mmax0=Max(c,d);}void pushdown(int root){ int flag = tree[root].flag; if(flag){ tree[root<<1].flag ^= 1; tree[root<<1|1].flag ^= 1; swap(tree[root<<1].mmax1,tree[root<<1].mmax0); swap(tree[root<<1].lm1,tree[root<<1].lm0); swap(tree[root<<1].rm1,tree[root<<1].rm0); swap(tree[root<<1|1].mmax1,tree[root<<1|1].mmax0); swap(tree[root<<1|1].lm1,tree[root<<1|1].lm0); swap(tree[root<<1|1].rm1,tree[root<<1|1].rm0); tree[root].flag=0; }}void build(int root,int l,int r){ tree[root].l=l,tree[root].r=r; if(l==r){ if(a[l]==1){ tree[root].mmax1=tree[root].lm1=tree[root].rm1=a[l]&1; tree[root].mmax0=tree[root].lm0=tree[root].rm0=a[l]^1; } else{ tree[root].mmax1=tree[root].lm1=tree[root].rm1=0;//a[l]&1; tree[root].mmax0=tree[root].lm0=tree[root].rm0=1;//a[l]^1; } tree[root].flag=0; return ; } int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); tree[root].flag=0; pushup(root);}void modify(int root,int pos,int val){ int l=tree[root].l,r=tree[root].r; if(pos==l&&val==r){ tree[root].flag ^= 1; swap(tree[root].mmax1,tree[root].mmax0); swap(tree[root].lm1,tree[root].lm0); swap(tree[root].rm1,tree[root].rm0); return ; } int mid=l+r>>1; pushdown(root); if(val<=mid) modify(root<<1,pos,val); else if(pos>mid) modify(root<<1|1,pos,val); else{ modify(root<<1,pos,mid); modify(root<<1|1,mid+1,val); } pushup(root);}int query(int root,int pos,int val){ int l=tree[root].l,r=tree[root].r; if(l==pos&&r==val) return tree[root].mmax1; pushdown(root); int mid=(l+r)>>1; if(val<=mid) return query(root<<1,pos,val); if(pos>mid) return query(root<<1|1,pos,val); int ll=query(root<<1,pos,mid); int rl=query(root<<1|1,mid+1,val); int a=tree[root<<1].rm1; if(a>tree[root<<1].r-pos+1) a=tree[root<<1].r-pos+1; int b=tree[root<<1|1].lm1; if(b>val-tree[root<<1|1].l+1) b=val-tree[root<<1|1].l+1; int ans = Max(ll,Max(rl,a+b)); return ans; }int main(){ int n,m,x,l,r; while(~scanf("%d",&n)){ for(register int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); scanf("%d",&m); for(register int i=1;i<=m;i++){ scanf("%d%d%d",&x,&l,&r); if(x==0) printf("%d\n",query(1,l,r)); else if(x==1) modify(1,l,r); } } return 0;}
- hdu 3911 Black and White 线段树维护01序列
- HDU--3911[Black And White] 线段树
- hdu 3911 Black And White 线段树
- HDU 3911 Black And White 线段树
- hdu 3911 Black And White(线段树)
- hdu 3911 Black And White 区间合并 线段树
- hdu 3911 Black And White(线段树)
- HDU 3911 Black And White(线段树区间合并)
- hdu 3911 Black And White 线段树区间合并
- HDU 3911 Black And White (线段树区间更新)
- hdu 3911 black and white 线段树区间合并
- hdu 3911 Black And White (线段树)
- hdu 3911 Black and White
- hdu 3911 Black And White
- hdu 3911 Black And White
- HDU 3911 Black And White
- HDU 3911 Black And White
- HDU 3911 Black And White
- 希尔排序的Java实现
- 剑指offer面试题46 求1+2+3…+n(java实现)
- VirtualBox 下centos7 网络配置
- codewars上的一道训练函数式编程思维的编程题
- Gosn对几种情况json数据解析
- hdu 3911 Black and White 线段树维护01序列
- MVC5中使用jQuery Post 二维数组和一维数组到Action
- java当中randomAccessFile文件随机读取对象的简单使用
- Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询
- 【poj1201】Intervals
- B
- 剑指offer面试题47 不用加减乘除做加法 (java实现)
- 异构数据源海量数据交换工具-Taobao DataX 下载和使用
- uva508 莫尔斯电码(Morse Mismatches)