hdu 3397 区间合并 + 异或处理。

来源:互联网 发布:淘宝购物车无法结算 ie 编辑:程序博客网 时间:2024/05/18 20:09

本题最困难处就是 operation 2 处理上

由于数据只有 0 和1 两个数字

所以当执行operation 2 处理时 对其异或即可。

#include <iostream>   #include <cstring>   #include <cstdio>   #include <algorithm>   using namespace std;  #define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int Maxn = 111111;  int sum[Maxn<<2], lmaxn[Maxn<<2], rmaxn[Maxn<<2], maxn[Maxn<<2];  int co[Maxn<<2];  void pushdown(int rt,int m){if(co[rt]!=-1){co[rt<<1]=co[rt<<1|1]=co[rt];maxn[rt<<1]=lmaxn[rt<<1]=rmaxn[rt<<1]=sum[rt<<1]=co[rt]?(m-(m>>1)):0;maxn[rt<<1|1]=lmaxn[rt<<1|1]=rmaxn[rt<<1|1]=sum[rt<<1|1]=co[rt]?(m>>1):0;co[rt]=-1;}}void pushup(int rt,int m){sum[rt]=sum[rt<<1]+sum[rt<<1|1];lmaxn[rt]=lmaxn[rt<<1];rmaxn[rt]=rmaxn[rt<<1|1];if(lmaxn[rt]==(m-(m>>1))) lmaxn[rt]+=lmaxn[rt<<1|1];if(rmaxn[rt]==(m>>1))  rmaxn[rt]+=rmaxn[rt<<1];maxn[rt]=max(max(maxn[rt<<1],maxn[rt<<1|1]),lmaxn[rt<<1|1]+rmaxn[rt<<1]);}void build(int l,int r,int rt){if(l==r){    scanf("%d",&sum[rt]);co[rt]=maxn[rt]=lmaxn[rt]=rmaxn[rt]=sum[rt]; //对其进行标志。该标志决定该数是啥。return ;}co[rt]=-1;int m=(l+r)>>1;build(lson);build(rson);pushup(rt,r-l+1);}void update(int L,int R,int c,int l,int r,int rt){if(L<=l&&r<=R){    co[rt]=c;sum[rt]=maxn[rt]=lmaxn[rt]=rmaxn[rt]=c?r-l+1:0;return ;}pushdown(rt,r-l+1);int m=(l+r)>>1;if(L<=m) update(L,R,c,lson);if(R>m) update(L,R,c,rson);pushup(rt,r-l+1);}void Xor(int L,int R,int l,int r,int rt){if(L<=l&&r<=R&&co[rt]!=-1)    //异或处理。换句话理解就是 当其完全是1 或者完全是 0 的时候 转换。{//在build()时已经对子叶进行标志了。子叶的co[rt]!=-1;co[rt]^=1;sum[rt]=maxn[rt]=lmaxn[rt]=rmaxn[rt]=co[rt]?r-l+1:0;return ;}pushdown(rt,r-l+1);int m=(l+r)>>1;if(L<=m) Xor(L,R,lson);if(R>m)  Xor(L,R,rson);pushup(rt,r-l+1);}int query(int L,int R,int l,int r,int rt){if(L<=l&&r<=R)return sum[rt];pushdown(rt,r-l+1);int m=(l+r)>>1,ret=0;if(L<=m)ret+=query(L,R,lson);if(R>m) ret+=query(L,R,rson);return ret;}int len(int L,int R,int l,int r,int rt){if(L==l&&r==R)return maxn[rt];pushdown(rt,r-l+1);int m=(l+r)>>1;if(R<=m) return len(L,R,lson);if(L>m)  return len(L,R,rson);int ans=max(len(L,m,lson),len(m+1,R,rson));int ret=min(lmaxn[rt<<1|1],R-m)+min(rmaxn[rt<<1],m-L+1);return max(ans,ret);}int main(){    int cas;scanf("%d",&cas);while(cas--){    int n,m;scanf("%d %d",&n,&m);n--;build(0,n,1);while(m--){    int c,l,r;scanf("%d %d %d",&c,&l,&r);if(c<=1)update(l,r,c,0,n,1);else if(c==2)Xor(l,r,0,n,1);else if(c==3)printf("%d\n",query(l,r,0,n,1));elseprintf("%d\n",len(l,r,0,n,1));}}return 0;}

0 0
原创粉丝点击