线段树求调qwq

P2572 [SCOI2010] 序列操作

cat_lover1 @ 2024-08-22 13:56:36

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,q,a[N],op,x,y,z;
#define tnii tuple<node,int,int>
struct node{
  int len;
  int sum;
  int cov,rev;
  array<int,3> mx[2];
  node operator+(tnii tt){
    auto&[o,h1,h2]=tt;
    //assert(cov==-1&&!rev&&o.cov==-1&&!o.rev);
    node tmp;
    tmp.cov=h1;
    tmp.rev=h2;
    tmp.sum=sum+o.sum;
    for(bool $:{0,1}){
      if(mx[$][0]==len) 
        tmp.mx[$][0]=len+o.mx[$][0];
      else tmp.mx[$][0]=mx[$][0];
      if(o.mx[$][1]==o.len) 
        tmp.mx[$][1]=o.len+mx[$][1];
      else tmp.mx[$][1]=o.mx[$][1];
      tmp.mx[$][2]=max({mx[$][2],o.mx[$][2],mx[$][1]+o.mx[$][0]});
    } 
    return tmp;
  }
  void flip(){
    sum=len-sum;
    if(cov!=-1) cov^=1;
    rev^=1;
    swap(mx[0],mx[1]);
  }
  void cover(int x){
    sum=x*len;
    cov=x;
    rev=0;
    mx[x][0]=mx[x][1]=mx[x][2]=len;
    mx[!x][0]=mx[!x][1]=mx[!x][2]=0;
  }
} t[N<<2];
#define tr int h,int l,int r
#define ls h*2
#define rs ls|1
#define mid (l+r>>1)
#define lson ls,l,mid
#define rson rs,mid+1,r
#define pushup(h) t[h]=t[ls]+tnii({t[rs],t[h].cov,t[h].rev})
void pushdown(int h){
  if(t[h].rev){
    t[h].rev=0;
    t[ls].flip();
    t[rs].flip();
  }
  if(t[h].cov!=-1){
    int &c=t[h].cov;
    t[ls].cover(c);
    t[rs].cover(c);
    c=-1;
  }
}
void build(tr){
  t[h].len=r-l+1;
  t[h].cov=-1;
  if(l==r){
    t[h].sum=a[l];
    t[h].mx[a[l]][0]=t[h].mx[a[l]][1]=t[h].mx[a[l]][2]=1;
    return;
  }
  build(lson);
  build(rson);
  printf("bp\n");
  pushup(h);
}
void update(tr,int x,int y,int z){
  if(x<=l&&r<=y) 
    return z!=-1?t[h].cover(z):t[h].flip();
  pushdown(h);
  if(x<=mid) update(lson,x,y,z);
  else update(rson,x,y,z);
  printf("up\n");
  pushup(h);
}
node query(tr,int x,int y){
  if(x<=l&&r<=y) 
    return t[h];
  pushdown(h);
  if(y<=mid) return query(lson,x,y);
  if(x>mid) return query(rson,x,y);
  printf("qp\n");
  return query(lson,x,y)+tnii({query(rson,x,y),-1,0});
}
main(){
  t[0].cov=-1;
  cin.tie(0)->sync_with_stdio(0);
  cin>>n>>q;
  for(int i=1;i<=n;++i) cin>>a[i];
  build(1,1,n);
  while(q--){
    cin>>op>>x>>y; ++x,++y;
    if(op<=1) update(1,1,n,x,y,op);
    if(op==2) update(1,1,n,x,y,-1);
    if(op==3) cout<<query(1,1,n,x,y).sum<<'\n';
    if(op==4) cout<<query(1,1,n,x,y).mx[1][2]<<'\n';
  }
}

|