经典线段树问题。
我们知道等差数列加上等差数列还是一个等差数列。
所以我们线段树维护区间的总和,当前位置的值,和公差即可。
对于求区间和,因为模数是根据输入的,我们发现模数只到了25,所以我们考虑计算出来mod=lcm(1,2,3,....25)
这样的mod一定时1到25中任意一个数的倍数。那么我们输出的时候就可以保证输入的模数能够整除所求的区间和。

#include <cstdio>
#include <algorithm>

using namespace std;
#define ll long long

const int mod = 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23;
const int inv2 = mod / 2 + 1;

struct Treert {
  int val, d, s;
};
Treert t[200010 * 4];

int n, q, op, l, r, x, y, a[200010];
void build(int rt , int l , int r)
{
  if(l == r)
   {
     t[rt] = {0 , 0 , a[l]} ;
     return ;
   }
   int mid = l + r >> 1 ;
   build(rt << 1 , l , mid) ;
   build(rt << 1 | 1 , mid + 1 , r) ;
   t[rt] = {0 , 0 , (t[rt << 1].s + t[rt << 1 | 1].s) % mod };
   return ;
}
void down(int rt , ll val , ll d , ll n)
{
  t[rt].val = (t[rt].val + val) % mod ;
  t[rt].d = (t[rt].d + d) % mod ;
  t[rt].s = (t[rt].s + (val + val + (n - 1) * d % mod)% mod * n % mod * inv2 % mod) % mod  ;
}
void update(int rt , ll l , ll r , ll ql , ll qr , ll val , ll d)
{
  if(qr < l || r < ql) return ;
  if(ql <= l && r <= qr)
   {
     down(rt , (val + (l - ql) * d % mod) % mod  , d , r - l + 1) ;
     return ;
   }
   int mid = l + r >> 1;
   down(rt << 1 , t[rt].val , t[rt].d , mid - l + 1) ;
   down(rt << 1 | 1 , (t[rt].val + (mid + 1 - l) * t[rt].d % mod )% mod , t[rt].d , r - mid) ;
   t[rt].val = 0 , t[rt].d = 0 ;
   update(rt << 1 , l , mid , ql , qr , val , d) ;
   update(rt << 1 | 1 , mid + 1 , r , ql , qr ,val , d) ;
   t[rt].s = (t[rt << 1].s + t[rt << 1 | 1].s ) % mod ;
   return ;
}
ll ask(ll rt , ll l , ll r , ll ql , ll qr)
{
  if(r < ql || l > qr) return 0 ;
  if(ql <= l && r <= qr) return t[rt].s % mod ;
  int mid = l + r >> 1;
  down(rt << 1 , t[rt].val , t[rt].d , mid - l + 1) ;
  down(rt << 1 | 1 , (t[rt].val + (mid + 1 - l) * t[rt].d % mod )% mod , t[rt].d , r - mid) ;
  t[rt].val = 0 , t[rt].d = 0 ;
  return (ask(rt << 1 , l , mid , ql , qr) + ask(rt << 1 | 1 , mid + 1 , r,  ql , qr) )% mod ;
}

int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
  build(1, 1, n);
  scanf("%d", &q);
  while (q--) {
    scanf("%d%d%d%d", &op, &l, &r, &x);
    if (op == 1) {
      scanf("%d", &y);
      update(1, 1, n, l, r, x, y);
    } else printf("%d\n", ask(1, 1, n, l, r) % x);
  }
  return 0;
}