【区间维护】线段树统计(染色细胞版)
经典线段树,区间修改,区间查询,比较麻烦
#include<bits/stdc++.h> using namespace std; #define N 1000005 void read(int &x){ int f=1;x=0;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} x*=f; } int n,m; int a[N]; struct node{ int l,r,lazy,cnt,Left,Right; #define l(x) tree[x].l #define r(x) tree[x].r #define lazy(x) tree[x].lazy #define cnt(x) tree[x].cnt #define Left(x) tree[x].Left #define Right(x) tree[x].Right }tree[N<<2]; void PushUp(int p){ cnt(p)=cnt(2*p)+cnt(2*p+1)-(Right(p*2)==Left(p*2+1)); Left(p)=Left(p*2); Right(p)=Right(p*2+1); } void PushDown(int p){ if(lazy(p)){ lazy(p*2)=lazy(p*2+1)=lazy(p); Left(p*2)=Right(p*2)=Left(p*2+1)=Right(p*2+1)=lazy(p); cnt(p*2)=cnt(p*2+1)=1; lazy(p)=0; } } void Build(int p,int l,int r){ l(p)=l,r(p)=r; if(l==r){ Left(p)=Right(p)=a[l]; cnt(p)=1; return; } int mid=(l+r)>>1; Build(p*2,l,mid); Build(p*2+1,mid+1,r); PushUp(p); } void Update(int p,int l,int r,int val){ if(l<=l(p)&&r>=r(p)){ lazy(p)=val; Left(p)=Right(p)=val; cnt(p)=1; return; } PushDown(p); int mid=(l(p)+r(p))>>1; if(l<=mid) Update(p*2,l,r,val); if(r>mid) Update(p*2+1,l,r,val); PushUp(p); } int Query(int p,int l,int r){ if(l<=l(p)&&r>=r(p)) return cnt(p); PushDown(p); int mid=(l(p)+r(p))>>1; int ret=0; if(l<=mid) ret=Query(p*2,l,r); if(r>mid) ret+=Query(p*2+1,l,r)-(ret&&Right(p*2)==Left(p*2+1)); return ret; } int main(){ read(n),read(m); for(int i=1;i<=n;++i) read(a[i]); Build(1,1,n); while(m--){ int c,x,y,z; read(c); read(x),read(y); if(x>y) swap(x,y); if(c==1){ read(z); Update(1,x,y,z); }else{ int ans=Query(1,x,y); printf("%d\n",ans); } /*for(int i=1;i<=n*2;++i){ //printf("%d %d %d %d %d %d\n",l(i),r(i),Left(i),Right(i),cnt(i),i); }*/ } return 0; }

浙公网安备 33010602011771号