Sequence operation

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7452    Accepted Submission(s): 2220

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]
 
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.
 
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
 

题解:测试数据对了但是一直re。。。。先贴着吧。。。

0,1,2,代表操作,0代表将区间内全部变为0,1代表区间内全部变为1,2代表区间内0,1取反

3,4代表查询,3代表查询区间内1的总数,4代表查询区间内最长连续1的个数

re代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int INF=0x3f3f3f3f;
#define mem(x,y) memset(x,y,sizeof(x))
#define SI(x) scanf("%d",&x)
#define PI(x) printf("%d",x)
#define SD(x,y) scanf("%lf%lf",&x,&y)
#define P_ printf(" ")
#define ll root<<1
#define rr root<<1|1
#define lson ll,l,mid
#define rson rr,mid+1,r
typedef long long LL;
const int MAXN=;
struct Node{
int len,n0,ln0,rn0,sum,v,lazy,x_or;
int n1,ln1,rn1;
Node init(){
SI(v);
n0=ln0=rn0=(v==);
n1=ln1=rn1=(v==);
sum=v;
}
};
Node tree[MAXN<<];
void XOR(int root,int v){
swap(tree[root].n0,tree[root].n1);
swap(tree[root].ln0,tree[root].ln1);
swap(tree[root].rn0,tree[root].rn1);
tree[root].sum=v-tree[root].sum;
if(tree[root].lazy!=-)tree[root].lazy^=;
//printf("%d %d %d %d %d %d\n",tree[root].n0,tree[root].ln0,tree[root].rn0,tree[root].n1,tree[root].ln1,tree[root].rn1);
}
void pushup(int root){
tree[root].sum=tree[ll].sum+tree[rr].sum;
tree[root].ln0=tree[ll].ln0;
tree[root].rn0=tree[rr].rn0;
if(tree[ll].ln0==tree[ll].len)tree[root].ln0+=tree[rr].ln0;
if(tree[rr].rn0==tree[rr].len)tree[root].rn0+=tree[ll].rn0;
tree[root].n0=max(max(tree[root].ln0,tree[root].rn0),tree[ll].rn0+tree[rr].ln0); tree[root].ln1=tree[ll].ln1;
tree[root].rn1=tree[rr].rn1;
if(tree[ll].ln1==tree[ll].len)tree[root].ln1+=tree[rr].ln1;
if(tree[rr].rn1==tree[rr].len)tree[root].rn1+=tree[ll].rn1;
tree[root].n1=max(max(tree[root].ln1,tree[root].rn1),tree[ll].rn1+tree[rr].ln1); }
void pushdown(int root,int v){
if(tree[root].lazy!=-){
tree[ll].lazy=tree[rr].lazy=tree[root].lazy;
tree[ll].ln0=tree[ll].n0=tree[ll].rn0=tree[root].lazy?:tree[ll].len;
tree[rr].ln0=tree[rr].n0=tree[rr].rn0=tree[root].lazy?:tree[rr].len;
tree[rr].ln1=tree[rr].n1=tree[rr].rn1=tree[root].lazy?tree[rr].len:;
tree[ll].ln1=tree[ll].n1=tree[ll].rn1=tree[root].lazy?tree[ll].len:;
tree[ll].sum=tree[root].lazy?tree[ll].len:;
tree[rr].sum=tree[root].lazy?tree[rr].len:;
/*
tree[root].sum=v;
tree[root].ln0=tree[root].rn0=tree[root].lazy?0:tree[root].len;
tree[root].ln1=tree[root].rn1=tree[root].lazy?tree[root].len:0;
*/
tree[ll].x_or=tree[rr].x_or=;
tree[root].lazy=-;
}
if(tree[root].x_or){
tree[ll].x_or^=;
tree[rr].x_or^=;
XOR(ll,tree[ll].len);
XOR(rr,tree[rr].len);
tree[root].x_or=;
}
}
void build(int root,int l,int r){
tree[root].len=r-l+;
tree[root].lazy=-;
tree[root].x_or=;
if(l==r){
tree[root].init();return;
}
int mid=(l+r)>>;
build(lson);build(rson);
pushup(root);
}
void update(int root,int l,int r,int A,int B,int c){
int mid=(l+r)>>;
pushdown(root,tree[root].len);
if(l>=A&&r<=B){
//printf("c=%d\n",c);
if(c<){
tree[root].lazy=c;
tree[root].sum=tree[root].lazy?tree[root].len:;
tree[root].n0=tree[root].ln0=tree[root].rn0=tree[root].lazy?:tree[root].len;
tree[root].n1=tree[root].ln1=tree[root].rn1=tree[root].lazy?tree[root].len:;
}
else{
tree[root].x_or=;
XOR(root,tree[root].len);
}
return;
}
pushdown(root,r-l+);
if(mid>=A)update(lson,A,B,c);
if(mid<B)update(rson,A,B,c);
pushup(root);
}
int query(int root,int l,int r,int A,int B,int c){
if(l>=A&&r<=B){
// printf("%d %d\n",tree[root].sum,tree[root].n1);
if(c==)return tree[root].sum;
else return tree[root].n1;
}
pushdown(root,r-l+);
int mid=(l+r)>>;
if(mid>=B)return query(lson,A,B,c);
else if(mid<A)return query(rson,A,B,c);
else{
int ans1=query(lson,A,mid,c);
int ans2=query(rson,mid+,B,c);
if(c==)return ans1+ans2;
else return max(max(ans1,ans2),min(mid-A+,tree[ll].rn1)+min(B-mid,tree[rr].ln1));
}
}
int main(){
int T,N,M;
SI(T);
while(T--){
SI(N);SI(M);
build(,,N-);
while(M--){
int p,a,b;
scanf("%d%d%d",&p,&a,&b);
if(p<=)update(,,N-,a,b,p);
else{
printf("%d\n",query(,,N-,a,b,p));
}
}
}
return ;
}

Sequence operation(线段树区间多种操作)的更多相关文章

  1. hdu 3397 Sequence operation (线段树 区间合并 多重标记)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意: 给你一串01串,有5种操作 0. 区间全部变为0 1.区间全部变为1 2.区间异或 3.询问 ...

  2. hdu 3397 Sequence operation 线段树 区间更新 区间合并

    题意: 5种操作,所有数字都为0或1 0 a b:将[a,b]置0 1 a b:将[a,b]置1 2 a b:[a,b]中的0和1互换 3 a b:查询[a,b]中的1的数量 4 a b:查询[a,b ...

  3. 线段树区间更新操作及Lazy思想(详解)

    此题题意很好懂:  给你N个数,Q个操作,操作有两种,‘Q a b ’是询问a~b这段数的和,‘C a b c’是把a~b这段数都加上c. 需要用到线段树的,update:成段增减,query:区间求 ...

  4. hdu-3397 Sequence operation 线段树多种标记

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3397 题目大意: 0 a b表示a-b区间置为0 1 a b表示a-b区间置为1 2 a b表示a- ...

  5. hdu3397 Sequence operation 线段树

    hdu3397 Sequence operation #include <bits/stdc++.h> using namespace std; ; struct node { /// l ...

  6. HDU 4578 Transformation (线段树区间多种更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=4578 题目大意:对于一个给定序列,序列内所有数的初始值为0,有4种操作.1:区间(x, y)内的所有数字全部加上 ...

  7. hdu 3397 Sequence operation 线段树

    题目链接 给出n个数, 每个数是0或1, 给5种操作, 区间变为1, 区间变为0, 区间0,1翻转, 询问区间内1的个数, 询问区间内最长连续1的个数. 需要将数组开成二维的, 然后区间0, 1翻转只 ...

  8. Transformation(线段树+HDU4578+多种操作+鬼畜的代码)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578 题目: 题意:n个数初始值为0,进行四种操作:1.将区间内的数字加c:2.将区间内的数字乘c:3 ...

  9. HDU-4578 Transformation(线段树的多种区间操作)

    http://acm.hdu.edu.cn/showproblem.php?pid=4578 Time Limit: 15000/8000 MS (Java/Others)    Memory Lim ...

随机推荐

  1. 根据群ID和用户Id查询 + string QueryQunByUserIdAndQunId(int userId, int qunId) V1.0

    #region  根据群ID和用户Id查询 + string QueryQunByUserIdAndQunId(int userId, int qunId)  V1.0 /// <summary ...

  2. 算法分析-堆排序 HeapSort 优先级队列

    堆排序的是集合了插入排序的单数组操作,又有归并排序的时间复杂度,完美的结合了2者的优点. 堆的定义 n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆. 情形1:ki < ...

  3. 计算机图形学--旋转变换(java)

    import java.awt.Color; import java.awt.Frame; import java.awt.Graphics; import java.awt.event.Window ...

  4. hdu 5586 Sum(dp+技巧)

    Problem Description There )mod10007.After that,the sum of n numbers should be as much as possible.Wh ...

  5. sharepoint 2013 reporting services 远程server返回错误: (500) 内部server错误。

    在sharepoint 2013部署reporting services过程中,点击管理中心,server上的服务.系统配置.提示了一个错误: 远程server返回错误: (500) 内部server ...

  6. ubuntu 下 apache+tomcat整合_(mod-jk方法)[转]

    整合的平台是Centos5环境如下: apache源代码包: httpd-2.2.11.tar.gz  下载地址http://labs.xiaonei.com/apache-mirror/httpd/ ...

  7. 显示GetLastError()的错误描述字符串

    void ShowLastError() { LPVOID lpMsgBuf; FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | //返回一个已分配的内 ...

  8. House Robber & House Robber II

    You are a professional robber planning to rob houses along a street. Each house has a certain amount ...

  9. c++多线程同步使用的对象

    线程的同步 Critical section(临界区)用来实现“排他性占有”.适用范围是单一进程的各线程之间.它是: ·         一个局部性对象,不是一个核心对象. ·         快速而 ...

  10. C++中将int转变成string和string转变成int

    int to string #include<iostream> #include<string> using namespace std; int main() { stri ...