Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using namespace std;
- #include <bits/stdc++.h>
- using ll = long long;
- const ll mod = 1e9 + 7;
- ll euclid(ll a, ll b, ll &x, ll &y) {
- if (!b) return x = 1, y = 0, a;
- ll d = euclid(b, a % b, y, x);
- return y -= a/b * x, d;
- }
- struct Mod {
- ll x;
- Mod(ll y) : Mod(y%mod+mod,0){}
- Mod(ll y,int) : x(y<mod?y:y-mod){}
- Mod operator+(Mod b) { return {x + b.x,0}; }
- Mod operator-(Mod b) { return {x - b.x + mod,0}; }
- Mod operator*(Mod b) { return {x * b.x % mod,0}; }
- Mod operator/(Mod b) { return *this * invert(b); }
- Mod invert(Mod a) {
- ll x,y;
- assert(euclid(a.x,mod,x,y)==1); return x;
- }
- Mod operator^(ll e) {
- if (!e) return Mod(1);
- Mod r = *this ^ (e / 2); r = r * r;
- return e&1 ? *this * r : r;
- }
- };
- struct Tree {
- vector<Mod> tree;
- vector<Mod> lazy;
- vector<Mod> prefixI;
- int n;
- Tree(int n, vector<Mod> pfi) : n(n), tree(4 * n, Mod(0)), lazy(4 * n, Mod(0)), prefixI(pfi) {}
- void push(int x, int l, int r) {
- int mid = (l + r) / 2;
- tree[x * 2] = tree[x * 2] + lazy[x] * (prefixI[mid] - prefixI[max(0, l - 1)]);
- lazy[x * 2] = lazy[x * 2] + lazy[x];
- tree[x * 2 + 1] = tree[x * 2 + 1] + lazy[x] * (prefixI[r] - prefixI[mid]);
- lazy[x * 2 + 1] = lazy[x * 2 + 1] + lazy[x];
- lazy[x] = 0;
- }
- void add(int x, int l, int r, int ql, int qr, Mod v) {
- if (l > qr || r < ql) return;
- if (l >= ql && r <= qr) {
- tree[x] = tree[x] + v * (prefixI[r] - prefixI[l - 1]);
- lazy[x] = lazy[x] + v;
- return;
- }
- push(x, l, r);
- int mid = (l + r) / 2;
- add(x * 2, l, mid, ql, qr, v);
- add(x * 2 + 1, mid + 1, r, ql, qr, v);
- tree[x] = tree[x * 2] + tree[x * 2 + 1];
- }
- void add(int l, int r, Mod v) { add(1, 0, n - 1, l, r, v); }
- Mod query(int x, int l, int r, int ql, int qr) {
- if (l > qr || r < ql) return 0;
- if (l >= ql && r <= qr) return tree[x];
- push(x, l, r);
- int mid = (l + r) / 2;
- return query(x * 2, l, mid, ql, qr) + query(x * 2 + 1, mid + 1, r, ql, qr);
- }
- Mod query(int l, int r) { return query(1, 0, n - 1, l, r); }
- };
- Mod poly(ll l, int i) {
- if (i == 0) return Mod(-l) * Mod(l * l) + Mod(6 * l * l) - Mod(11 * l) + Mod(6);
- if (i == 1) return Mod(3 * l * l) - Mod(12 * l) + Mod(11);
- if (i == 2) return Mod(-3 * l) + Mod(6);
- else return 1;
- }
- int main() {
- cin.tie(0)->sync_with_stdio(0);
- int n, q;
- cin >> n >> q;
- n += 5;
- vector<vector<Mod>> sum(4, vector<Mod>(n, Mod(0)));
- for (int i = 1; i < n; i++) {
- sum[0][i] = sum[0][i - 1] + Mod(1);
- sum[1][i] = sum[1][i - 1] + Mod(i);
- sum[2][i] = sum[2][i - 1] + Mod(i) * Mod(i);
- sum[3][i] = sum[3][i - 1] + Mod(i) * Mod(i) * Mod(i);
- }
- vector<Tree> trees = {
- Tree(n, sum[0]),
- Tree(n, sum[1]),
- Tree(n, sum[2]),
- Tree(n, sum[3])
- };
- while (q--) {
- int t, l, r;
- cin >> t >> l >> r;
- if (t == 1) {
- for (int i = 0; i < 4; i++) trees[i].add(l, r, poly(l, i));
- }
- else if (t == 2) {
- for (int i = 0; i < 4; i++) trees[i].add(l, r, Mod(0) - poly(l, i));
- }
- else {
- Mod v = 0;
- for (int i = 0; i < 4; i++) v = v + trees[i].query(l, r);
- cout << v.x << "\n";
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment