线段树2 模板 70分 求改
查看原帖
线段树2 模板 70分 求改
246331
mystic_qwq楼主2023/11/17 16:17

祝大佬rp++

#include<cstdio>
#define ll long long
const int maxn=1e5+1;
int n,q,mod,op,x,y,k;
struct Node{
  int l,r,len;
  ll sum,t1=1,t2;//tm,ta
  Node *ls,*rs;
  bool IN(int L,int R){return L<=l&&r<=R;}
  bool OUT(int L,int R){return R<l||r<L;}
  void mg1(int x){sum=sum*x%mod,t1=t1*x%mod,t2=t2*x%mod;}
  void mg2(int x){sum=(sum+x*len)%mod,t2=(t2+x)%mod;}
  void pushup(){sum=(ls->sum+rs->sum)%mod;}
  void pushdown(){
    ls->mg1(t1),rs->mg1(t1);
    ls->mg2(t2),rs->mg2(t2);
    t1=1,t2=0;
  }
  void upd(int L,int R){
    if(IN(L,R)){
      if(op&1)mg1(k);
      else mg2(k);
    }
    else if(!OUT(L,R)){
      pushdown();
      ls->upd(L,R),rs->upd(L,R);
      pushup();
    }
  }
  int qry(int L,int R){
    if(IN(L,R))return sum;
    if(!OUT(L,R)){
      pushdown();
      return (ls->qry(L,R)+rs->qry(L,R))%mod;
    }
    return 0;
  }
}mem[maxn<<1],*pool=mem;
Node* New(int L,int R){
  auto x=pool++;
  x->l=L,x->r=R,x->len=R-L+1;
  if(L^R){
    int M=L+R>>1;
    x->ls=New(L,M),x->rs=New(M+1,R);
    x->pushup();
  }
  else scanf("%lld",&(x->sum)),x->sum%=mod;
  return x;
}
main(){
  scanf("%d%d%d",&n,&q,&mod);
  auto rot=New(1,n);
  while(q--){
    scanf("%d%d%d",&op,&x,&y);
    if(op^3)scanf("%d",&k),rot->upd(x,y);
    else printf("%lld\n",rot->qry(x,y));
    //test();
  }
}
2023/11/17 16:17
加载中...