Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <sstream>
- #include <fstream>
- #include <iomanip>
- #include <cstdio>
- #include <cstdlib>
- #include <algorithm>
- #include <queue>
- #include <stack>
- #include <set>
- #include <map>
- #include <list>
- #include <vector>
- #include <string>
- #include <cstring>
- #include <cmath>
- #include <ctime>
- #include <cassert>
- #include <bitset>
- using namespace std;
- #define forn(i, n) for(int i = 0; i < (int)(n); i++)
- #define forn1(i, n) for(int i = 1; i <= (int)(n); i++)
- #define all(a) (a).begin(), (a).end()
- #define sz(a) (int)((a).size())
- #define mp make_pair
- #define pb push_back
- #define X first
- #define Y second
- #define x first
- #define y second
- #define y1 __y1
- #define sqr(x) ((x) * (x))
- typedef long long li;
- typedef long double ld;
- typedef pair<int, int> pt;
- const int INF = (int)(1e9);
- const li INF64 = (li)(INF) * (li)(INF);
- const ld eps = 1e-9;
- const ld pi = ld(3.1415926535897932384626433832795);
- inline bool in(int i, int j, int n, int m)
- {
- return i >= 1 && i <= n && j >= 1 && j <= m;
- }
- inline int myrand()
- {
- return (rand() ^ (rand() << 15));
- }
- const int dx[] = {-1, 0, 1, 0};
- const int dy[] = {0, 1, 0, -1};
- const int N = 2e5 + 555;
- const int L = 300;
- li a[N];
- li sumB[N / L + 1];
- li addB[N / L + 1];
- li startB[N / L + 1];
- li n, m;
- li Na[N];
- li t[N], x[N], y[N];
- li idxB[N];
- li cntAdd[N / L + 1];
- li addtoB[N];
- li starts[N];
- li ADD[N];
- inline void gen()
- {
- n = 100000, m = 100000;
- forn(i, m)
- {
- t[i] = rand() % 2 + 1;
- int x = myrand() % n + 1, y = myrand() % n + 1;
- if(x > y)
- swap(x, y);
- ::x[i] = x, ::y[i] = y;
- }
- /*
- n = 10;
- m = 100;
- t[0] = 1, x[0] = 1, y[0] = 10;
- t[1] = 1, x[1] = 3, y[1] = 7;
- t[2] = 2, x[2] = 2, y[2] = 4;
- for(int i = 3; i < m; i++)
- {
- t[i] = 2;
- int x = rand() % n + 1, y = rand() % n + 1;
- if(x > y)
- swap(x, y);
- ::x[i] = x, ::y[i] = y;
- }*/
- return;
- }
- inline bool read()
- {
- //gen();
- //return true;
- if(scanf("%d %d", &n, &m) != 2)
- return false;
- forn(i, m)
- {
- assert(scanf("%d %d %d", &t[i], &x[i], &y[i]) == 3);
- }
- return true;
- }
- inline void naiveUpd(int lf, int rg)
- {
- li start = 2, add = 4;
- for(int i = lf; i <= rg; i++)
- {
- Na[i] += start;
- start += add;
- add += 2;
- }
- return;
- }
- const li MOD = INF + 7;
- inline void add(li &a, const li &b)
- {
- a += b;
- //if(a >= MOD)
- // a -= MOD;
- return;
- }
- inline int naiveGet(int lf, int rg)
- {
- li ans = 0;
- for(int i = lf; i <= rg; i++)
- {
- ans = (ans + Na[i]) % MOD;
- }
- return int(ans);
- }
- inline void upd(int lf, int rg)
- {
- int LB = idxB[lf];
- int RB = idxB[rg];
- if(LB == RB)
- {
- li start = 2, addd = 4;
- for(int i = lf; i <= rg; i++)
- {
- add(a[i], start);
- add(sumB[LB], start);
- add(start, addd);
- add(addd, 2);
- }
- return;
- }
- li start = 2, addd = 4;
- for(int i = lf; i <= LB * L; i++)
- {
- add(a[i], start);
- add(sumB[LB], start);
- add(start, addd);
- add(addd, 2);
- }
- //int cnt = LB * L - lf;
- //int last = 2 + (cnt - 1) * 2;
- for(int i = LB + 1; i <= RB - 1; i++)
- {
- cntAdd[i]++;
- int id = (i - 1) * L + 1 - lf + 1;
- /*cerr << "i == " << i << endl;
- cerr << "id == " << id << endl;
- cerr << "starts ADD == " << starts[id] << ' ' << ADD[id] << endl;*/
- add(sumB[i], addtoB[id]);
- add(startB[i], starts[id]);
- add(addB[i], ADD[id]);
- }
- //cerr << "RBdx == " << (RB - 1) * L + 1 << endl;
- start = starts[(RB - 1) * L + 1 - lf + 1];
- addd = ADD[(RB - 1) * L + 1 - lf + 1];
- //cerr << "start addd == " << start << ' ' << addd << endl;
- for(int i = (RB - 1) * L + 1; i <= rg; i++)
- {
- add(a[i], start);
- add(sumB[RB], start);
- add(start, addd);
- add(addd, 2);
- }
- return;
- }
- li binpow(li a, li b)
- {
- if(b == 0)
- return 1;
- if(b % 2 == 1)
- return (a * binpow(a, b - 1)) % MOD;
- li cur = binpow(a, b / 2) % MOD;
- return (cur * cur) % MOD;
- }
- li mul = 1LL;
- inline int get(int lf, int rg)
- {
- int LB = idxB[lf];
- int RB = idxB[rg];
- if(LB == RB)
- {
- li ans = 0;
- for(int i = lf; i <= rg; i++)
- {
- //add(ans, a[i]);
- }
- /*int cnt = min(L, n - LB * L);
- int first = startB[LB];
- int last = int(first * 1LL * (cnt - 1) % MOD);
- add(last, first);
- int sum = int((first + last) * 1LL * cnt / 2 % MOD);*/
- for(int i = lf; i <= rg; i++)
- {
- li first = addB[LB];
- li lfidx = (LB - 1) * L + 1;
- li cnt = i - lfidx;
- li last = li((first + (cnt - 1) * 1LL * cntAdd[LB] * 2));
- li ff = first % MOD;
- li ll = ((first + (cnt - 1) * 1LL * cntAdd[LB] % MOD)) % MOD;
- li sum = li((first + last) * 1LL * cnt / 2);
- li ssum = (first + last) * 1LL * cnt % MOD;
- ssum = (ssum * mul) % MOD;
- add(ssum, startB[LB]);
- add(ssum, a[i]);
- add(ans, ssum);
- }
- assert(ans >= 0);
- return ans % MOD;
- }
- li ans = 0;
- for(int i = lf; i <= LB * L; i++)
- {
- li first = addB[LB];
- li lfidx = (LB - 1) * L + 1;
- li cnt = i - lfidx;
- li last = li((first + (cnt - 1) * 1LL * cntAdd[LB] * 2));
- li ff = first % MOD;
- li ll = ((first + (cnt - 1) * 1LL * cntAdd[LB] % MOD)) % MOD;
- li sum = li((first + last) * 1LL * cnt / 2);
- li ssum = (first + last) * 1LL * cnt % MOD;
- ssum = (ssum * mul) % MOD;
- add(ssum, startB[LB]);
- add(ssum, a[i]);
- add(ans, ssum);
- }
- for(int i = LB + 1; i <= RB - 1; i++)
- {
- add(ans, sumB[i]);
- ans %= MOD;
- }
- for(int i = (RB - 1) * L + 1; i <= rg; i++)
- {
- //add(ans, a[i]);
- }
- for(int i = (RB - 1) * L + 1; i <= rg; i++)
- {
- li first = addB[RB];
- li lfidx = (RB - 1) * L + 1;
- li cnt = i - lfidx;
- li last = li((first + (cnt - 1) * 1LL * cntAdd[RB] * 2));
- li ff = first % MOD;
- li ll = ((first + (cnt - 1) * 1LL * cntAdd[RB] % MOD)) % MOD;
- li sum = li((first + last) * 1LL * cnt / 2);
- li ssum = (first + last) * 1LL * cnt % MOD;
- ssum = (ssum * mul) % MOD;
- add(ssum, startB[RB]);
- add(ssum, a[i]);
- add(ans, ssum);
- }
- assert(ans >= 0);
- return ans % MOD;
- }
- inline void solve()
- {
- for(int i = 1; i <= n; i++)
- {
- int idx = i / L + 1;
- if(i % L == 0)
- idx--;
- idxB[i] = idx;
- }
- forn(i, m)
- {
- int l = x[i], r = y[i];
- int t = ::t[i];
- //cerr << "QEURY" << endl;
- //cerr << t << ' ' << l << ' ' << r << endl;
- if(t == 1)
- {
- upd(l, r);
- //naiveUpd(l, r);
- }
- else
- {
- int ans = get(l, r);
- printf("%d\n", ans);
- /*int nans = naiveGet(l, r);
- if(ans != nans)
- {
- cerr << ans << ' ' << nans << endl;
- assert(false);
- }
- assert(ans == nans);*/
- }
- }
- /*forn1(i, 10)
- {
- cerr << "addB[i] == " << addB[i] << ' ' << startB[i] << endl;
- }
- forn1(i, n)
- cerr << a[i] << ' ';
- cerr << endl;*/
- return;
- }
- li arr[N];
- li sums[N];
- int main() {
- #ifdef _DEBUG
- assert(freopen("input.txt", "rt", stdin));
- assert(freopen("output.txt", "wt", stdout));
- #endif
- cout << setprecision(10) << fixed;
- cerr << setprecision(10) << fixed;
- srand(int(time(NULL)));
- mul = binpow(2, MOD - 2);
- //for( ; ; )
- {
- //cerr << "!" << endl;
- assert(read());
- //cerr << "!" << endl;
- li ss = 2, dd = 4;
- //cerr << "n == " << n << endl;
- for(int i = 1; i <= n; i++)
- {
- //cerr << "i == " << i << ' ' << ss << endl;
- arr[i] = ss;
- ss += dd;
- dd += 2;
- }
- //forn1(i, 10)
- // cerr << arr[i] << ' ';
- //cerr << endl;
- for(int i = 1; i <= n; i++)
- {
- sums[i] = sums[i - 1] + arr[i];
- }
- for(int i = 1; i <= n; i++)
- {
- starts[i] = li(arr[i]);
- ADD[i] = li((arr[i + 1] - arr[i]));
- }
- for(int i = 1; i <= n; i++)
- {
- int rg = i + L - 1;
- if(i <= n)
- {
- addtoB[i] = li((sums[rg] - sums[i - 1]));
- }
- }
- solve();
- }
- #ifdef _DEBUG
- cerr << "TIME == " << clock() << " ms" << endl;
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement