您的位置:首页 > 其它

hdu 3397 线段树

2015-04-22 22:03 405 查看
题意: 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]

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

嗯嗯

2015-07-26:专题复习

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define MOD 1000000007
const int INF=0x3f3f3f3f;
const double eps=1e-5;
#define cl(a) memset(a,0,sizeof(a))
#define ts printf("*****\n");
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root 1,n,1
#define mid ((l+r)>>1)
const int MAXN=100010;
int n,m,t,Min,tt;
int msum1[MAXN<<2],col[MAXN<<2],lsum1[MAXN<<2],rsum1[MAXN<<2];
int msum0[MAXN<<2],lsum0[MAXN<<2],rsum0[MAXN<<2],xxor[MAXN<<2];
int sum1[MAXN<<2],sum0[MAXN<<2];
void fun1(int rt,int m,int val)     //改变区间内0/1的变化
{
msum1[rt]=lsum1[rt]=rsum1[rt]=sum1[rt]=val?m:0;
msum0[rt]=lsum0[rt]=rsum0[rt]=sum0[rt]=val?0:m;
}
void fun2(int rt)
{
swap(msum1[rt],msum0[rt]);
swap(lsum1[rt],lsum0[rt]);
swap(rsum1[rt],rsum0[rt]);
swap(sum1[rt],sum0[rt]);
}

void pushup(int rt,int m)
{
sum1[rt]=sum1[rt<<1]+sum1[rt<<1|1];
lsum1[rt]=lsum1[rt<<1];
rsum1[rt]=rsum1[rt<<1|1];
if(lsum1[rt]==(m-(m>>1)))    lsum1[rt]+=lsum1[rt<<1|1];
if(rsum1[rt]==(m>>1))    rsum1[rt]+=rsum1[rt<<1];
msum1[rt]=max(lsum1[rt<<1|1]+rsum1[rt<<1],max(msum1[rt<<1],msum1[rt<<1|1]));

sum0[rt]=sum0[rt<<1]+sum0[rt<<1|1];
lsum0[rt]=lsum0[rt<<1];
rsum0[rt]=rsum0[rt<<1|1];
if(lsum0[rt]==(m-(m>>1)))    lsum0[rt]+=lsum0[rt<<1|1];
if(rsum0[rt]==(m>>1))    rsum0[rt]+=rsum0[rt<<1];
msum0[rt]=max(lsum0[rt<<1|1]+rsum0[rt<<1],max(msum0[rt<<1],msum0[rt<<1|1]));
}
void build(int l,int r,int rt)
{
col[rt]=-1;
xxor[rt]=0;
if(l==r)
{
int num;
scanf("%d",&num);
msum1[rt]=lsum1[rt]=rsum1[rt]=sum1[rt]=num?1:0;
msum0[rt]=lsum0[rt]=rsum0[rt]=sum0[rt]=num?0:1;
return;
}
build(lson);
build(rson);
pushup(rt,r-l+1);
}
void pushdown(int rt,int m)
{
if(col[rt]!=-1)
{
xxor[rt<<1]=xxor[rt<<1|1]=0;
col[rt<<1]=col[rt<<1|1]=col[rt];
fun1(rt<<1,m-(m>>1),col[rt]);
fun1(rt<<1|1,m>>1,col[rt]);
col[rt]=-1;
}
else if(xxor[rt])
{
if(col[rt<<1]!=-1)
{
col[rt<<1]^=1;
fun1(rt<<1,m-(m>>1),col[rt<<1]);
}
else
{
xxor[rt<<1]^=1;
fun2(rt<<1);                //最大连续1的变化有点麻烦,必须要重新开一个最大连续0的变量
}
if(col[rt<<1|1]!=-1)
{
col[rt<<1|1]^=1;
fun1(rt<<1|1,(m>>1),col[rt<<1|1]);
}
else
{
xxor[rt<<1|1]^=1;
fun2(rt<<1|1);
}
xxor[rt]=0;
}
}
void update(int L,int R,int val,int l,int r,int rt)
{
if(l>=L&&r<=R)
{
if(val<=1)
{
xxor[rt]=0;
col[rt]=val;
fun1(rt,r-l+1,val);
}
else
{
if(col[rt]!=-1)
{
col[rt]^=1;
fun1(rt,r-l+1,col[rt]);
}
else
{
xxor[rt]^=1;
fun2(rt);
}
}
return;
}
pushdown(rt,r-l+1);
if(L<=mid) update(L,R,val,lson);
if(R>mid) update(L,R,val,rson);
pushup(rt,r-l+1);
}
int query1(int L,int R,int l,int r,int rt)  //查询区间内1的个数
{
if(l>=L&&r<=R)
{
return sum1[rt];
}
pushdown(rt,r-l+1);
int ans=0;
if(L<=mid) ans+=query1(L,R,lson);
if(R>mid) ans+=query1(L,R,rson);
return ans;
}
int query2(int L,int R,int l,int r,int rt)  //查询区间内最长连续1的个数
{
if(l>=L&&r<=R)
{
return msum1[rt];
}
pushdown(rt,r-l+1);

if(R<=mid) return query2(L,R,lson);
if(L>mid) return query2(L,R,rson);
int a=query2(L,R,lson);
int b=query2(L,R,rson);
a=max(a,b);
b=min(mid-L+1,rsum1[rt<<1])+min(R-mid,lsum1[rt<<1|1]);
return max(a,b);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
int t,n,m,op,a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
build(root);
while(m--)
{
scanf("%d%d%d",&op,&a,&b);
a++,b++;
if(op<=2) update(a,b,op,root);
else
{
if(op==3) printf("%d\n",query1(a,b,root));
else printf("%d\n",query2(a,b,root));
}
}
}
return 0;
}


View Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100010;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int num0[maxn<<2],num1[maxn<<2];
int lb0[maxn<<2],lb1[maxn<<2];
int rb0[maxn<<2],rb1[maxn<<2];
int mx1[maxn<<2],mx0[maxn<<2];
int col[maxn<<2];
int xxor[maxn<<2];
int num;
int max(int a,int b){
return a>b?a:b;
}
int min(int a,int b){
return a<b?a:b;
}
void pushup(int rt,int m)
{
lb0[rt]=lb0[rt<<1];rb0[rt]=rb0[rt<<1|1];
if(lb0[rt]==m-(m>>1)) lb0[rt]+=lb0[rt<<1|1];
if(rb0[rt]==(m>>1))  rb0[rt]+=rb0[rt<<1];

lb1[rt]=lb1[rt<<1];rb1[rt]=rb1[rt<<1|1];
if(lb1[rt]==m-(m>>1)) lb1[rt]+=lb1[rt<<1|1];
if(rb1[rt]==(m>>1))  rb1[rt]+=rb1[rt<<1];

num0[rt]=num0[rt<<1]+num0[rt<<1|1];
num1[rt]=num1[rt<<1]+num1[rt<<1|1];

mx1[rt]=max(mx1[rt<<1],mx1[rt<<1|1]);
mx1[rt]=max(mx1[rt],rb1[rt<<1]+lb1[rt<<1|1]);

mx0[rt]=max(mx0[rt<<1],mx0[rt<<1|1]);
mx0[rt]=max(mx0[rt],rb0[rt<<1]+lb0[rt<<1|1]);
}
void build(int l,int r,int rt){
col[rt]=-1; xxor[rt]=0;
if(l==r){
scanf("%d",&num);
num0[rt]=lb0[rt]=rb0[rt]=mx0[rt]=(num?0:1);
num1[rt]=lb1[rt]=rb1[rt]=mx1[rt]=(num?1:0);
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt,r-l+1);
}
void init(int rt,int m,int cmd){
lb0[rt]=rb0[rt]=mx0[rt]=num0[rt]=m*(1-cmd);
lb1[rt]=rb1[rt]=mx1[rt]=num1[rt]=m*cmd;
}
void change(int rt){
swap(lb0[rt],lb1[rt]);
swap(rb0[rt],rb1[rt]);
swap(mx0[rt],mx1[rt]);
swap(num0[rt],num1[rt]);
}
void pushdown(int rt,int m){
if(col[rt]!=-1){
col[rt<<1]=col[rt<<1|1]=col[rt];
xxor[rt<<1]=xxor[rt<<1|1]=0;
init(rt<<1,m-(m>>1),col[rt]);
init(rt<<1|1,(m>>1),col[rt]);
col[rt]=-1;
}
else if(xxor[rt]){
if(col[rt<<1]!=-1){
col[rt<<1]^=1;
init(rt<<1,m-(m>>1),col[rt<<1]);
}
else {
xxor[rt<<1]^=1;
change(rt<<1);
}
if(col[rt<<1|1]!=-1){
col[rt<<1|1]^=1;
init(rt<<1|1,(m>>1),col[rt<<1|1]);
}
else {
xxor[rt<<1|1]^=1;
change(rt<<1|1);
}
xxor[rt]=0;
}
}
void update(int L,int R,int cmd,int l,int r,int rt){
if(L<=l&&r<=R){
if(cmd<=1){
xxor[rt]=0;//取消异或标记
col[rt]=cmd;//真个区间被完全覆盖为cmd
init(rt,r-l+1,cmd);
}
else {
if(col[rt]!=-1){//被完全覆盖,全是0或者全是1,相当于取反
col[rt]^=1;
init(rt,r-l+1,col[rt]);
}
else {
xxor[rt]^=1;
change(rt);
}
}
return ;
}
pushdown(rt,r-l+1);
int m=(l+r)>>1;
if(L<=m) update(L,R,cmd,lson);
if(R>m) update(L,R,cmd,rson);
pushup(rt,r-l+1);
}
int query1(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R)  return num1[rt];
pushdown(rt,r-l+1);
int m=(l+r)>>1;
int ans=0;
if(L<=m) ans+=query1(L,R,lson);
if(R>m) ans+=query1(L,R,rson);
return ans;
}
int  query2(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R) {
return mx1[rt];
}
pushdown(rt,r-l+1);
int m=(l+r)>>1;
if(R<=m) return query2(L,R,lson);
if(L>m) return query2(L,R,rson);
int a=query2(L,R,lson);
int b=query2(L,R,rson);
a=a>b?a:b;
b=min(m-L+1,rb1[rt<<1])+min(R-m,lb1[rt<<1|1]);
return a>b?a:b;
}
int main(){
int t,n,m,op,a,b;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
build(0,n-1,1);
while(m--){
scanf("%d%d%d",&op,&a,&b);
if(op<=2) update(a,b,op,0,n-1,1);
else {
if(op==3) printf("%d\n",query1(a,b,0,n-1,1));
else printf("%d\n",query2(a,b,0,n-1,1));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: