Sequence operation
Total Submission(s): 8068 Accepted Submission(s): 2416
Problem Description
lxhgww got a sequence contains n characters which are all '0's or '1's.
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
Input
T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
Output
For each output operation , output the result.
Sample Input
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
Sample Output
5 2 6 5
Author
lxhgww&&shǎ崽
Source
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=3397
总结:
好久没写线段树,最近想复习一下,就找了这道以前觉得最复杂的区间合并来练手,上次做这道题还是一年半之前的8月集训,翻翻当时HDU上的记录,这道题整整调了3天。当时对pushdown和pushup这两个操作的理解还没有到位,两种标记处理的很拙劣。现在写线段树的境界有所提高,拿出来重新做,结果还是WA了4遍才过,所以写下这篇博客,记录一下这次错的几个地方:
(1)第一个,翻转操作标记只是置1,忘记了偶数次翻转的抵消;
(2)第二个,手残,区间合并的一个右边区间的左边连续1个数llb打成rrb,比赛的话写完代码一定要仔细查一遍;
(3)第三个,区间合并是有条件的,忽略了mid必须在[a,b]之间的判断;
(4)第四个,一个操作参数2打成3,原因是这题操作标签是0~4,印象中成了1~5,检查代码各种感觉不会错的细小的地方也要想一下!
AC代码:
最后附上这次写的姿势比较优美的代码:
import java.io.*;
public class Main {
static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static int nextInt() throws IOException
{
in.nextToken();
return (int)in.nval;
}
static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
static int T,n,m,a,b,op,maxn=100000;
static int[] aa=new int[maxn];
static int[] ss=new int[maxn<<2];
static int[] lz=new int[maxn<<2];
static int[] re=new int[maxn<<2];
static int[] lla=new int[maxn<<2];
static int[] rra=new int[maxn<<2];
static int[] mma=new int[maxn<<2];
static int[] llb=new int[maxn<<2];
static int[] rrb=new int[maxn<<2];
static int[] mmb=new int[maxn<<2];
static void pushup(int k,int l,int r)
{
int mid=(l+r)/2;
ss[k]=ss[k*2+1]+ss[k*2+2];
lla[k]=lla[k*2+1]+(lla[k*2+1]==mid+1-l?lla[k*2+2]:0);
rra[k]=rra[k*2+2]+(rra[k*2+2]==r-mid?rra[k*2+1]:0);
mma[k]=Math.max(rra[k*2+1]+lla[k*2+2],Math.max(mma[k*2+1],mma[k*2+2]));
llb[k]=llb[k*2+1]+(llb[k*2+1]==mid+1-l?llb[k*2+2]:0);
rrb[k]=rrb[k*2+2]+(rrb[k*2+2]==r-mid?rrb[k*2+1]:0);
mmb[k]=Math.max(rrb[k*2+1]+llb[k*2+2],Math.max(mmb[k*2+1],mmb[k*2+2]));
}
static void pushdown(int k,int l,int r)
{
int mid=(l+r)/2;
if(lz[k]!=-1)
{
up(l,r,k*2+1,l,mid,lz[k]);
up(l,r,k*2+2,mid+1,r,lz[k]);
}
if(re[k]==1)
{
up(l,r,k*2+1,l,mid,2);
up(l,r,k*2+2,mid+1,r,2);
}
lz[k]=-1;re[k]=0;
}
static void build(int k,int l,int r)
{
lz[k]=-1;re[k]=0;
if(l==r)
{
lla[k]=rra[k]=mma[k]=1-aa[l];
llb[k]=rrb[k]=mmb[k]=ss[k]=aa[l];
return;
}
int mid=(l+r)/2;
build(k*2+1,l,mid);
build(k*2+2,mid+1,r);
pushup(k,l,r);
}
static void up(int a,int b,int k,int l,int r,int op)
{
if(a>r||b<l) return;
if(a<=l&&r<=b)
{
if(op==2)
{
ss[k]=r-l+1-ss[k];
re[k]=(re[k]+1)%2;
int c;
c=lla[k];lla[k]=llb[k];llb[k]=c;
c=rra[k];rra[k]=rrb[k];rrb[k]=c;
c=mma[k];mma[k]=mmb[k];mmb[k]=c;
}
else
{
lz[k]=op;re[k]=0;
int x=op==0?0:r-l+1;
ss[k]=llb[k]=rrb[k]=mmb[k]=x;
lla[k]=rra[k]=mma[k]=r-l+1-x;
}
}
else
{
int mid=(l+r)/2;
pushdown(k,l,r);
up(a,b,k*2+1,l,mid,op);
up(a,b,k*2+2,mid+1,r,op);
pushup(k,l,r);
}
}
static int sum(int a,int b,int k,int l,int r)
{
if(a>r||b<l) return 0;
if(a<=l&&r<=b) return ss[k];
int mid=(l+r)/2;
pushdown(k,l,r);
return sum(a,b,k*2+1,l,mid)+sum(a,b,k*2+2,mid+1,r);
}
static int len(int a,int b,int k,int l,int r)
{
if(a>r||b<l) return 0;
if(a<=l&&r<=b) return mmb[k];
int mid=(l+r)/2,res=0;
pushdown(k,l,r);
if(a<=mid&&mid<b)
{
res+=Math.min(mid+1-a,rrb[k*2+1]);
res+=Math.min(b-mid,llb[k*2+2]);
}
res=Math.max(res,len(a,b,k*2+1,l,mid));
res=Math.max(res,len(a,b,k*2+2,mid+1,r));
return res;
}
public static void main(String[] args) throws IOException {
T=nextInt();
while(T-->0)
{
n=nextInt();m=nextInt();
for(int i=0;i<n;i++)
aa[i]=nextInt();
build(0,0,n-1);
while(m-->0)
{
op=nextInt();
a=nextInt();b=nextInt();
if(op==3)
out.println(sum(a,b,0,0,n-1));
else if(op==4)
out.println(len(a,b,0,0,n-1));
else up(a,b,0,0,n-1,op);
}
out.flush();
}
}
}