HDOJ 题目3397 Sequence operation(线段树区间覆盖异或合并)
2015-09-02 00:30
405 查看
Sequence operation
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7203 Accepted Submission(s): 2153
[align=left]Problem Description[/align]
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]
[align=left]Input[/align]
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.
[align=left]Output[/align]
For each output operation , output the result.
[align=left]Sample Input[/align]
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
[align=left]Sample Output[/align]
5 2 6 5
[align=left]Author[/align]
lxhgww&&shǎ崽
[align=left]Source[/align]
HDOJ Monthly Contest – 2010.05.01
[align=left]Recommend[/align]
lcy | We have carefully selected several similar problems for you: 1828 1542 2871 1255 3333
这么多操作结合起来真是恶心啊,0把区间赋值0,1把区间都赋值成1,2区间异或,3查询区间1的个数,4查询区间连续的1的长度
为何我是如此的弱啊
ac代码
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #define max(a,b) (a>b?a:b) #define min(a,b) (a>b?b:a) using namespace std; #define maxn 100010 struct s { int ml0,mr0,mx0; int ml1,mr1,mx1; int sum; int cover,Xor; }node[maxn<<2]; void pushup(int tr,int m) { node.ml0=node[tr<<1].ml0; node .ml1=node[tr<<1].ml1; node .mr0=node[tr<<1|1].mr0; node .mr1=node[tr<<1|1].mr1; if(node[tr<<1].ml0==(m-(m>>1))) node .ml0+=node[tr<<1|1].ml0; if(node[tr<<1|1].mr0==(m>>1)) node .mr0+=node[tr<<1].mr0; node .mx0=max(node[tr<<1].mx0,node[tr<<1|1].mx0); node .mx0=max(node .mx0,node[tr<<1].mr0+node[tr<<1|1].ml0); if(node[tr<<1].ml1==(m-(m>>1))) node .ml1+=node[tr<<1|1].ml1; if(node[tr<<1|1].mr1==(m>>1)) node .mr1+=node[tr<<1].mr1; node .mx1=max(node[tr<<1].mx1,node[tr<<1|1].mx1); node .mx1=max(node .mx1,node[tr<<1].mr1+node[tr<<1|1].ml1); node .sum=node[tr<<1].sum+node[tr<<1|1].sum; } void fxor(int tr,int m) { swap(node .ml0,node .ml1); swap(node .mr0,node .mr1); swap(node .mx0,node .mx1); node .sum=m-node .sum; } void build(int l,int r,int tr) { node .cover=-1; node .Xor=0; if(l==r) { int x; scanf("%d",&x); node .ml0=node .mr0=node .mx0=(x==0); node .ml1=node .mr1=node .mx1=(x==1); node .cover=x; node .sum=x; return; } int mid=(l+r)>>1; build(l,mid,tr<<1); build(mid+1,r,tr<<1|1); pushup(tr,r-l+1); } void pushdown(int tr,int m) { if(m==1) return; if(node .cover!=-1) { node[tr<<1].cover=node[tr<<1|1].cover=node .cover; node[tr<<1].Xor=node[tr<<1|1].Xor=0; if(node .cover) { node[tr<<1].ml1=node[tr<<1].mr1=node[tr<<1].mx1=(m-(m>>1)); node[tr<<1].ml0=node[tr<<1].mr0=node[tr<<1].mx0=0; node[tr<<1].sum=(m-(m>>1)); node[tr<<1|1].ml1=node[tr<<1|1].mr1=node[tr<<1|1].mx1=(m>>1); node[tr<<1|1].ml0=node[tr<<1|1].mr0=node[tr<<1|1].mx0=0; node[tr<<1|1].sum=(m>>1); } else { node[tr<<1].ml1=node[tr<<1].mr1=node[tr<<1].mx1=0; node[tr<<1].ml0=node[tr<<1].mr0=node[tr<<1].mx0=(m-(m>>1)); node[tr<<1].sum=0; node[tr<<1|1].ml1=node[tr<<1|1].mr1=node[tr<<1|1].mx1=0; node[tr<<1|1].ml0=node[tr<<1|1].mr0=node[tr<<1|1].mx0=(m>>1); node[tr<<1|1].sum=0; } node .cover=-1; } if(node .Xor) { node[tr<<1].Xor^=1; node[tr<<1|1].Xor^=1; fxor(tr<<1,m-(m>>1)); fxor(tr<<1|1,m>>1); node .Xor=0; } } void update(int L,int R,int l,int r,int tr,int op) { pushdown(tr,r-l+1);//先向下跟新啊。。 if(L<=l&&r<=R) { if(op==2) { node .Xor=1; fxor(tr,r-l+1); } else { int m=(r-l)+1; node .cover=op; if(op) { node .ml1=node .mr1=node .mx1=m; node .ml0=node .mr0=node .mx0=0; node .sum=m; } else { node .ml1=node .mr1=node .mx1=0; node .ml0=node .mr0=node .mx0=m; node .sum=0; } } return; } int mid=(l+r)>>1; if(L<=mid) update(L,R,l,mid,tr<<1,op); if(R>mid) update(L,R,mid+1,r,tr<<1|1,op); pushup(tr,r-l+1); } int query_sum(int L,int R,int l,int r,int tr) { if(L<=l&&r<=R) { return node .sum; } pushdown(tr,r-l+1); int mid=(l+r)>>1; int ans1=0; int ans2=0; if(L<=mid) ans1=query_sum(L,R,l,mid,tr<<1); if(R>mid) ans2=query_sum(L,R,mid+1,r,tr<<1|1); // pushup(tr,r-l+1); return ans1+ans2; } int query_max1(int L,int R,int l,int r,int tr) { if(L<=l&&r<=R) { return node .mx1; } pushdown(tr,r-l+1); int mid=(l+r)>>1; int ans=0; if(R<=mid) ans=query_max1(L,R,l,mid,tr<<1); else if(L>mid) ans=query_max1(L,R,mid+1,r,tr<<1|1); else { int ans1=query_max1(L,mid,l,mid,tr<<1); int ans2=query_max1(mid+1,R,mid+1,r,tr<<1|1); int ans3=min(node[tr<<1].mr1,mid-L+1)+min(node[tr<<1|1].ml1,R-(mid+1)+1); ans=max(ans1,max(ans2,ans3)); } // pushup(tr,r-l+1); return ans; } int main() { int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); build(1,n,1); while(m--) { int op,x,y; scanf("%d%d%d",&op,&x,&y); x++; y++; if(op<3) update(x,y,1,n,1,op); else { if(op==3) { printf("%d\n",query_sum(x,y,1,n,1)); } else { printf("%d\n",query_max1(x,y,1,n,1)); } } } } } 相关文章推荐
- ios开发之UI基础--应用管理xib-九宫格布局
- C#StringBuilder的使用
- LeetCode_DP_Unique Binary Search Trees
- POJ2299 Ultra-QuickSort(树状数组)
- iOS 7 新特性 - UIKit Dynamics
- Prefer Literal Syntax over the Equivalent methods
- UItableCell 设计
- ios开发之UI基础--懒加载
- POJ Ultra-QuickSort (树状数组+离散化)
- UIImageview的contentmode介绍
- LeetCode_DP_Unique Paths II
- Leetcode Unique Binary Search Trees
- 百度Ueditor编辑器取消多图上传对话框中的图片搜索
- ios开发之UI基础--transframe属性
- LeetCode_DP_Unique Paths
- Android开发自定义UI组件
- iOS开发之UI基础--纯代码控件.frame,center,bounds属性
- 【转】C# string和StringBuilder的区别
- iOS开发之UI基础--Button基础
- UVA 11324 The Largest Clique (强连通分量,dp)