30pts求调分块
查看原帖
30pts求调分块
1235819
_std_xzh楼主2025/1/4 11:11
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n , q , m , p[100005] , op , x , y;
ll tg1[1005] , tg2[1005] , sum[1005] , bl;
ll k , a[100005];
template<class T>inline T read(){
	T f = 1 , x = 0;
	char c = getchar();
	while(!isdigit(c)){if(c == '-')f = -1;c = getchar();}
	while(isdigit(c)){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
	return f * x;
}
inline void pushdown(int x){
	int lx = p[x];
	for(int i = x;p[i] == lx;i++)a[i] = (a[i] * tg1[lx] + tg2[lx]) % m;
	for(int i = x - 1;p[i] == lx;i--)a[i] = (a[i] * tg1[lx] + tg2[lx]) % m;
	tg1[lx] = 1;
	tg2[lx] = 0;
}
void init(){
	bl = sqrt(n);
	for(int i = 1;i <= n;i++){p[i] = (i - 1) / bl + 1;sum[p[i]] = (sum[p[i]] + a[i]) % m;tg1[p[i]] = 1;}
}
inline void update(int l , int r , ll k , int t){
	int lk = p[l] , rk = p[r];
	pushdown(l);
	if(t == 1){
		if(lk == rk){
			for(int i = l;i <= r;i++){a[i] = (a[i] * k) % m;sum[lk] += a[i] * (k - 1);}
            sum[lk] %= m;
		}else{
			pushdown(r);
			for(int i = l;p[i] == lk;i++){a[i] = (a[i] * k) % m;sum[lk] += a[i] * (k - 1);}
            sum[lk] %= m;
			for(int i = lk + 1;i < rk;i++){sum[i] = (sum[i] * k) % m;tg1[i] = (tg1[i] * k) % m;tg2[i] = (tg2[i] * k) % m;}
			for(int i = r;p[i] == rk;i--){a[i] = (a[i] * k) % m;sum[rk] += a[i] * (k - 1);}
            sum[rk] %= m;
		}
	}else{
		if(lk == rk){
			for(int i = l;i <= r;i++){a[i] = (a[i] + k) % m;sum[lk] += k;}
            sum[lk] %= m;
		}else{
			pushdown(r);
			for(int i = l;p[i] == lk;i++){a[i] = (a[i] + k) % m;sum[lk] += k;}
            sum[lk] %= m;
			for(int i = lk + 1;i < rk;i++){sum[i] = (sum[i] + bl * k) % m;tg2[i] = (tg2[i] + k) % m;}
			for(int i = r;p[i] == rk;i--){a[i] = (a[i] + k) % m;sum[rk] += k;}
            sum[rk] %= m;
		}
	}
}
inline int query(int l , int r){
	int lk = p[l] , rk = p[r];
    ll ans = 0;
	if(lk == rk){
		for(int i = l;i <= r;i++)ans += a[i] * tg1[lk] + tg2[lk];
	}else{
		for(int i = l;p[i] == lk;i++)ans += a[i] * tg1[lk] + tg2[lk];
		for(int i = lk + 1;i < rk;i++)ans += sum[i];
		for(int i = r;p[i] == rk;i--)ans += a[i] * tg1[rk] + tg2[rk];
	}
	return ans % m;
}
int main(){
	n = read<int>() , q = read<int>() , m = read<int>();
	for(int i = 1;i <= n;i++)a[i] = read<ll>();
	init();
	while(q--){
		op = read<int>() , x = read<int>() , y = read<int>();
		if(op == 1){k = read<ll>();update(x , y , k , 1);}
		else if(op == 2){k = read<ll>();update(x , y , k , 2);}
		else cout << query(x , y) << '\n';
	}
	return 0;
}
2025/1/4 11:11
加载中...