0pts求调,悬赏一关
查看原帖
0pts求调,悬赏一关
494539
_String楼主2023/8/4 16:01
#include<iostream>
//#include <cstdio>
using namespace std;
int n,q,temp,x,y;
long long k,m,a[100001];
struct Tree{
	long long d,zm,za; 
}t[400000];
void build(int p,int l,int r){
	t[p].za=0;
	t[p].zm=1;
	if(l==r){
		t[p].d=a[l]%m;
		return;
	}
	int mid=(l+r)>>1,ls=p<<1,rs=ls|1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	t[p].d=(t[ls].d+t[rs].d)%m;
	return;
//	t[p].zm=1; 
//    t[p].za=0;
//    if(l==r){
//        t[p].d=a[l];
//    }else{
//        int m=(l+r)/2;
//        build(p*2,l,m);
//        build(p*2+1, m+1, r);
//        t[p].d=t[p*2].d+t[p*2+1].d;
//    }
//    t[p].d%=m;
//    return ;
}
inline void push_down(int p,int l,int r){
	int mid=(l+r)>>1,ls=p<<1,rs=ls|1;
	t[ls].d=(t[ls].d*t[p].zm+(mid-l+1)*t[p].za)%m;
	t[rs].d=(t[rs].d*t[p].zm+(r-mid)*t[p].za)%m;
	t[ls].za=(t[ls].za*t[p].zm+t[p].za)%m;
	t[rs].za=(t[rs].za*t[p].zm+t[p].za)%m;
	t[ls].zm=(t[ls].zm*t[ls].zm)%m;
	t[rs].zm=(t[rs].zm*t[rs].zm)%m;
	t[p].za=0;
	t[p].zm=1;
	return;
}
void multiply(int p,int l,int r,int ql,int qr){
	if(l==ql && r==qr){
		t[p].d=(t[p].d*k)%m;
		t[p].za=(t[p].za*k)%m;
		t[p].zm=(t[p].zm*k)%m;
		return;
	}
	push_down(p,ql,qr);
	int mid=(ql+qr)>>1,ls=p<<1,rs=ls|1;
	if(r<=mid) multiply(ls,l,r,ql,mid);
	else if(l>mid) multiply(rs,l,r,mid+1,qr);
	else multiply(ls,l,mid,ql,mid),multiply(rs,mid+1,r,mid+1,qr);
	t[p].d=(t[ls].d+t[rs].d)%m;
	return;
//	if(r<ql || qr<l) return ;
//   	if(l<=ql && qr<=r){
//       t[p].d=(t[p].d*k)%m;
//       t[p].zm=(t[p].zm*k)%m;
//       t[p].za=(t[p].za*k)%m;
//       return ;
//   }
//   push_down(p,ql,qr);
//   int m=(ql+qr)/2;
//   multiply(p*2, ql, m, l, r);
//   multiply(p*2+1, m+1, qr, l, r);
//   t[p].d=(t[p*2].d+t[p*2+1].d)%m;
//   return ;
}
void addition(int p,int l,int r,int ql,int qr){
	if(l==ql && r==qr){
		t[p].d=(t[p].d+k*(r-l+1))%m;
		t[p].za=(t[p].za+k)%m;
		return;
	}
	push_down(p,ql,qr);
	int mid=(ql+qr)>>1,ls=p<<1,rs=ls|1;
	if(r<=mid) addition(ls,l,r,ql,mid);
	else if(l>mid) addition(rs,l,r,mid+1,qr);
	else addition(ls,l,mid,ql,mid),addition(rs,mid+1,r,mid+1,qr);
	t[p].d=(t[ls].d+t[rs].d)%m;
	return;
//	if(r<ql || qr<l) return ;
//   	if(l<=ql && qr<=r){
//       	t[p].za=(t[p].za+k)%m;
//       	t[p].d=(t[p].d+k*(qr-+1))%m;
//       	return ;
//   	}
//   	push_down(p, ql, qr);
//   	int m=(ql+qr)/2;
//   	addition(p*2, ql, m, l, r);
//   	addition(p*2+1, m+1, qr, l, r);
//   	t[p].d=(t[p*2].d+t[p*2+1].d)%m;
//   	return ;
}
long long query(int p,int l,int r,int ql,int qr){
	if(r<ql || l>qr) return 0;
	if(l<=qr && r>=qr) return t[p].d;
	push_down(p,ql,qr);
	int m=(ql+qr)>>1;
	return (query(p<<1,l,r,ql,m)+query((p<<1)|1,l,r,m+1,qr))%m;
}
int main(){
//	freopen("【模板】线段树 2.in","r",tdin);
//	freopen("【模板】线段树 2.out","w",tdout);
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>q>>m;
	for(int i=1;i<=n;++i) cin>>a[i];
	build(1,1,n);
	while(q--){
		cin>>temp>>x>>y;
		switch(temp){
			case 1:
				cin>>k;
				k-=(k/m)*m;
				multiply(1,x,y,1,n);
				break;
			case 2:
				cin>>k;
				k-=(k/m)*m;
				addition(1,x,y,1,n);
				break;
			default:
				cout<<query(1,x,y,1,n)<<endl;
				break;
		}
	}
//	scanf("%d%d%d", &n, &q, &m);
//    for(int i=1; i<=n; i++) scanf("%lld", &a[i]);
//    build(1, 1, n);
//    while(q--){
//        int chk;
//        scanf("%d", &chk);
//        int x, y;
//        long long k;
//        if(chk==1){
//            scanf("%d%d%lld", &x, &y, &k);
//            multiply(1, x, y, 1, n);
//        }else if(chk==2){
//            scanf("%d%d%lld", &x, &y, &k);
//            addition(1, x, y, 1, n);
//        }else{
//            scanf("%d%d", &x, &y);
//            printf("%lld\n", query(1, x, y, 1, n));
//        }
//    }
	return 0;
}
2023/8/4 16:01
加载中...