线段树求调(样例没过)

P3373 【模板】线段树 2

```cpp #include <bits/stdc++.h>//Test #define ll long long #define zb x*2 #define yb x*2+1 //左右节点 using namespace std; const int N=1e5+10; struct Seg{ ll tag,sum,mul; int l,r; #define l(x) st[x].l #define r(x) st[x].r #define sum(x) st[x].sum #define tag(x) st[x].tag #define mul(x) st[x].mul }st[4*N]; ll a[N]; int n,m,q; void pushup(int x){ sum(x)=(sum(zb)+sum(yb))%m; } void pushdown(int x){ sum(zb)=(sum(zb)*mul(x)%m+tag(x)*(r(zb)-l(zb)+1)%m)%m; sum(yb)=(sum(yb)*mul(x)%m+tag(x)*(r(yb)-l(yb)+1)%m)%m; mul(zb)=(mul(zb)*mul(x))%m; mul(yb)=(mul(yb)*mul(x))%m; tag(zb)=(tag(zb)*mul(x)+tag(x))%m; tag(yb)=(tag(yb)*mul(x)+tag(x))%m; //cout<<yb<<" &&&&"<<sum(yb)<<" "<<mul(yb)<<" "<<tag(x)<<endl; tag(x)=0; mul(x)=1; } void build(int x,int l,int r){ l(x)=l;r(x)=r;mul(x)=1; if(l==r){ sum(x)=a[l]%m; return; } int mid=(l+r)>>1; build(zb,l,mid); build(yb,mid+1,r); pushup(x); } void modify(int x,int l,int r,ll k){ if(l<=l(x)&&r>=r(x)){ sum(x)=(sum(x)%m+k*(r(x)-l(x)+1)%m)%m; tag(x)=(tag(x)%m+k%m)%m; return; } pushdown(x); int mid=(l(x)+r(x))>>1; if(l<=mid) modify(zb,l,r,k); if(r>mid) modify(yb,l,r,k); pushup(x); } // void modify2(int x,int l,int r,ll k){ if(l<=l(x)&&r>=r(x)){ sum(x)=(sum(x)*k)%m; mul(x)=(mul(x)*k)%m; tag(x)=(tag(x)*k)%m; return; } pushdown(x); int mid=(l(x)+r(x))>>1; if(l<=mid) modify2(zb,l,r,k); if(r>mid) modify2(yb,l,r,k); pushup(x); } ll query(int x,int l,int r){ if(l<=l(x)&&r>=r(x)){ return sum(x)%m; } pushdown(x); ll ans=0; int mid=(l(x)+r(x))>>1; if(l<=mid) ans=(ans%m+query(zb,l,r)%m)%m; if(r>mid) ans=(ans%m+query(yb,l,r)%m)%m; return ans%m; } int main(){ cin>>n>>q>>m; for(int i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,1,n); for(int i=1;i<=q;i++){ int op; scanf("%d",&op); int x,y; ll k; if(op==1){ scanf("%d%d%lld",&x,&y,&k); modify2(1,x,y,k); // printf("@@@%lld %lld\n",sum(5),tag(2)); // cout<<"**"<<mul(2)<<endl; //cout<<sum(8)<<" "<<sum(9)<<" "<<sum(5)<<" "<<sum(6)<<endl; } else if(op==2){ scanf("%d%d%lld",&x,&y,&k); modify(1,x,y,k); //printf("@@@%lld %lld\n",sum(5),tag(2)); } else{ scanf("%d%d",&x,&y); //printf("@@@%lld %lld\n",sum(5),tag(2)); printf("%lld\n",query(1,x,y)); } } return 0; } /* 2 5 100000 3 5 2 1 2 3 1 1 2 10 3 1 2 2 1 2 3 3 1 2 */
by HugeSB @ 2023-10-14 18:58:44


首先67、68行的modify写错了,应该是modify2…… 然后是取模挂了,pushdown里的mul也得取模,然后两两相加时最好也取个模 ( •̀ ω •́ )y
by HugeSB @ 2023-10-14 19:00:52


|