1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
#include <bits/stdc++.h> using namespace std; #define resetIO(x) \ freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout) #define debug(fmt, ...) \ fprintf(stderr, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) template <class _Tp> inline _Tp& read(_Tp& x) { bool sign = false; char ch = getchar(); double tmp = 1; for (; !isdigit(ch); ch = getchar()) sign |= (ch == '-'); for (x = 0; isdigit(ch); ch = getchar()) x = x * 10 + (ch ^ 48); return sign ? (x = -x) : x; } template <class _Tp> inline void write(_Tp x) { if (x < 0) putchar('-'), x = -x; if (x > 9) write(x / 10); putchar((x % 10) ^ 48); } bool m_be; using ll = long long; const int MAXN = 2e5 + 10; const int MAXB = 450; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int n, q, a[MAXN]; int blk, bn, bl[MAXB], br[MAXB], pos[MAXN]; int bsum[MAXB], psum[MAXN], sum[MAXB][MAXB]; inline void add(int& x, int y) { (x += y), (x >= MOD) && (x -= MOD); } inline int vadd(int x, int y) { return x += y, x >= MOD ? x - MOD : x; } bool m_ed; signed main() { read(n), read(q); for (int i = 1; i <= n; ++i) read(a[i]); blk = ceil(sqrt(n)); for (int l = 1; l <= n; l += blk) { int r = min(n, l + blk - 1); ++bn, bl[bn] = l, br[bn] = r; for (int i = l; i <= r; ++i) pos[i] = bn; } for (int i = 1; i <= n; ++i) add(psum[i], a[i]), add(bsum[pos[i]], a[i]); while (q--) { int op; if (read(op) == 1) { int x, y, z; read(x), read(y), read(z), add(z, 0); if (x <= blk) { for (int i = y; i <= x; ++i) add(sum[x][i], z); } else { for (int i = y; i <= n; i += x) add(psum[i], z), add(bsum[pos[i]], z); } } else { int l, r, ans = 0; read(l), read(r); if (pos[l] == pos[r]) { for (int i = l; i <= r; ++i) add(ans, psum[i]); } else { for (int i = l; i <= br[pos[l]]; ++i) add(ans, psum[i]); for (int i = bl[pos[r]]; i <= r; ++i) add(ans, psum[i]); for (int i = pos[l] + 1; i < pos[r]; ++i) add(ans, bsum[i]); } for (int i = 1; i <= blk; ++i) { int bl = (l - 1) / i + 1, br = (r - 1) / i + 1; int pl = (l - 1) % i + 1, pr = (r - 1) % i + 1; add(ans, vadd(sum[i][pr], MOD - sum[i][pl - 1])); if (bl != br) add(ans, 1ll * (br - bl) * sum[i][i] % MOD); } write(ans), putchar('\n'); } } return 0; }
|