scoi2010序列操作

四川oi t了我两天  

原来只是一个宏定义。。。

真的什么心思都有了
整个人都好了。

宏定义  ?运算的max
max(A(),B())
就是  A()>B()?A():B()
四倍慢。。。
我还用了几次
于是从1秒多瞬间到了10妙多

WTF  i m really drunk



#include<cstdio>
#define N 100010
#define loop(i,j,k) for(int i=j;i<=k;i++)
int n,m;
int s[N];
int op,u,v;
struct TREE {
	int l,r,la;
	int L0,R0,K0,S0;
	int L1,R1,K1,S1;
	TREE () {la=-1;}
}t[N*3];
int max (int a,int b){
	if(a>b)
	return a;
	return b;
}
void readdata () {
	scanf("%d%d",&n,&m);
	loop(i,1,n)
		scanf("%d",&s[i]);
}
void pushup (int M) {
	int ls = (M << 1);
	int rs = (ls | 1);	
	t[M].S0 = t[ls].S0 + t[rs].S0 ;
	t[M].L0 = t[ls].L0 ;	
	t[M].R0 = t[rs].R0 ;	
	if(t[ls].L0 == t[ls].r - t[ls].l + 1)	
	t[M].L0 += t[rs].L0 ;
	if(t[rs].R0 == t[rs].r - t[rs].l + 1)
	t[M].R0 += t[ls].R0;	
	t[M].K0 = max (t[ls].K0 , t[rs].K0 );
	t[M].K0 = max (t[M].K0 , t[ls].R0 + t[rs].L0 );	
	t[M].S1 = t[ls].S1 + t[rs].S1 ;
	t[M].L1 = t[ls].L1 ;
	t[M].R1 = t[rs].R1 ;	
	if(t[ls].L1 == t[ls].r - t[ls].l + 1)	
	t[M].L1 += t[rs].L1 ;
	if(t[rs].R1 == t[rs].r - t[rs].l + 1)
	t[M].R1 += t[ls].R1;	
	t[M].K1 = max (t[ls].K1 , t[rs].K1 );
	t[M].K1 = max (t[M].K1, t[ls].R1 + t[rs].L1 );
}
void build (int l,int r,int M) {
	t[M].l = l;
	t[M].r = r;	
	if(l==r) {
		if(s[l]) {
			t[M].K1=t[M].L1=t[M].R1=t[M].S1=1;
			t[M].K0=t[M].L0=t[M].R0=t[M].S0=0;
		}
		else {
			t[M].K1=t[M].L1=t[M].R1=t[M].S1=0;
			t[M].K0=t[M].L0=t[M].R0=t[M].S0=1;
		}
		return ;
	}	
	int mid = (l + r) / 2;	
	build (l,mid,M<<1);
	build (mid+1,r,M << 1 | 1);			
	pushup(M);
}
inline void SWAP (int &a,int &b) {
	int temp=a;
	a=b;
	b=temp;
}
inline void work (int M,int f) {
	if(f<=1) {
		t[M].L0 = t[M].R0 = t[M].S0 =t[M].K0 = (f^1) * (t[M].r - t[M].l + 1);
		t[M].L1 = t[M].R1 = t[M].S1 =t[M].K1 = f * (t[M].r - t[M].l + 1);
	}
	else {
		SWAP(t[M].L0 ,t[M].L1 );
		SWAP(t[M].R0 ,t[M].R1 );
		SWAP(t[M].K0 ,t[M].K1 );
		SWAP(t[M].S0 ,t[M].S1 );
	}
}
inline void lazy (int M,int f) {
	if(t[M].la == -1 || (f==1||f==0) ) {  
		t[M].la = f;
	}
	else {
		if(t[M].la == 2) {
			t[M].la = -1;
		}
		else t[M].la = (t[M].la + 1)&1;
	}
}
void pushdown (int M) {
	int ls=(M<<1);
	int rs=(ls|1);
	lazy(ls,t[M].la );
	lazy(rs,t[M].la );
	work(ls,t[M].la );
	work(rs,t[M].la );
	t[M].la = -1;
}
void change (int f,int l,int r,int M) {
	int ls = (M << 1);
	int rs = (ls | 1);	
	if(t[M].l == l && t[M].r == r) {
		work(M,f);
		lazy(M,f);
		return;
	}
	if(t[M].la != -1)
		pushdown(M);
	int mid = (t[M].l + t[M].r )>>1;	
	if(l>mid) {
		change (f,l,r,rs);
	}
	else {
		if(r<=mid) {
			change (f,l,r,ls);
		}
		else {
			change (f,l,mid,ls);
			change (f,mid+1,r,rs);
		}
	}
	pushup(M);	
}
int find (int f,int l,int r,int M) {
	int ls = (M << 1);
	int rs = (ls | 1);
	if(l==t[M].l && r== t[M].r) {
		if(f==3)
		return t[M].S1 ;
		return t[M].K1 ;
	}
	if(t[M].la != -1)
		pushdown(M);
	int mid = (t[M].l + t[M].r )>>1;
	if(l>mid){
		return find(f,l,r,rs);
	}
	else {
		if(r<=mid) {
			return find (f,l,r,ls);
		}
		else {
			if(f==3)
			return find (f,l,mid,ls)+find (f,mid+1,r,rs);
			return max ( ( t[ls].R1  > mid-l+1 ? mid-l+1 : t[ls].R1)  +  ( t[rs].L1 > r-mid ? r-mid : t[rs].L1), max(find (f,l,mid,ls),find (f,mid+1,r,rs))  );
		}
	}
}
void solve () {
	loop(i,1,m) {
		scanf("%d%d%d",&op,&u,&v);
		if(op<=2)
			change (op,1+u,1+v,1);
		else
			printf("%d\n",find(op,1+u,1+v,1));
	}
}
int main () {
	readdata () ;
	build (1,n,1) ;
	solve () ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值