Advertisement
Guest User

LazyPropagationWithPolynomial

a guest
Jul 15th, 2015
605
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.03 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <algorithm>
  4. #include <vector>
  5.  
  6. using namespace std;
  7.  
  8. #define ll long long
  9. ll M = 1000000007;
  10.  
  11. ll calcZero(ll l, ll r) {
  12.     return (ll)(r - l) % M;
  13. }
  14.  
  15. ll calcFirst(ll l, ll r) {
  16.     return (ll)((r*(r - 1) - l*(l - 1)) / 2) % M;
  17. }
  18.  
  19. ll calcSecond(ll l, ll r) {
  20.     return (ll)((r*(r - 1)*(2 * r - 1) - l*(l - 1)*(2 * l - 1)) / 6) % M;
  21. }
  22.  
  23. ll calcSum(ll l, ll r, ll a, ll b, ll c) {
  24.     return (a*calcSecond(l, r) + b*calcFirst(l, r) + c*calcZero(l, r) + 3*M) % M;
  25. }
  26.  
  27. struct vertex{
  28.  
  29.     int num;
  30.     ll left, right;
  31.     ll a, b, c;
  32.     bool unPushed;
  33.     ll sum;
  34.  
  35.     vertex() {
  36.         num = 0;
  37.         a = b = c = 0;
  38.         unPushed = false;
  39.         sum = 0;
  40.     }
  41.  
  42.     void print() {
  43.         cerr << num << " - num\n";
  44.         cerr << left << " " << right << " l r\n";
  45.         cerr << a << " " << b << " " << c << " a b c\n";
  46.         cerr << unPushed << " unPushed\n";
  47.         cerr << sum << " sum\n";
  48.         cerr << "\n";
  49.     }
  50.    
  51. };
  52.  
  53. class PolynomialSegmentTree {
  54.  
  55.     int length;
  56.     vector<vertex> vertice;
  57.  
  58.     void build(int num, ll l, ll r) {
  59.         vertice[num].num = num;
  60.         vertice[num].left = l, vertice[num].right = r;
  61.         if (r > l + 1) {
  62.             ll m = (l + r) / 2;
  63.             build(2 * num + 1, l, m);
  64.             build(2 * num + 2, m, r);
  65.         }
  66.     }
  67.  
  68.     void makePush(int num) {
  69.         vertice[num].unPushed = false;
  70.         if (vertice[num].right > vertice[num].left + 1){
  71.             vertice[2 * num + 1].a += vertice[num].a;
  72.             vertice[2 * num + 1].b += vertice[num].b;
  73.             vertice[2 * num + 1].c += vertice[num].c;
  74.  
  75.             vertice[2 * num + 2].a += vertice[num].a;
  76.             vertice[2 * num + 2].b += vertice[num].b;
  77.             vertice[2 * num + 2].c += vertice[num].c;
  78.  
  79.             vertice[2 * num + 1].a %= M;
  80.             vertice[2 * num + 1].b %= M;
  81.             vertice[2 * num + 1].c %= M;
  82.  
  83.             vertice[2 * num + 2].a %= M;
  84.             vertice[2 * num + 2].b %= M;
  85.             vertice[2 * num + 2].c %= M;
  86.  
  87.             vertice[2 * num + 1].unPushed = true;
  88.             vertice[2 * num + 2].unPushed = true;
  89.         }
  90.         vertice[num].sum = (vertice[num].sum + calcSum(vertice[num].left, vertice[num].right, vertice[num].a, vertice[num].b, vertice[num].c) + 3*M) % M;
  91.         vertice[num].a = 0;
  92.         vertice[num].b = 0;
  93.         vertice[num].c = 0;
  94.     }
  95.  
  96.     void add(int num, ll l, ll r, ll a, ll b, ll c) {
  97.  
  98.         if (l >= r)
  99.             return;
  100.  
  101.         ll left = vertice[num].left;
  102.         ll right = vertice[num].right;
  103.        
  104.         if (left == l && right == r) {
  105.             vertice[num].a += a;
  106.             vertice[num].b += b;
  107.             vertice[num].c += c;
  108.             vertice[num].unPushed = true;
  109.             return;
  110.         }
  111.        
  112.         vertice[num].sum = (vertice[num].sum + calcSum(l, r, a, b, c)) % M;
  113.  
  114.         ll mid = (left + right) / 2;
  115.  
  116.         add(2 * num + 1, l, min(mid, r), a, b, c);
  117.         add(2 * num + 2, max(mid, l), r, a, b, c);
  118.  
  119.     }
  120.  
  121.     ll askSum(int num, ll l, ll r) {
  122.         if (l >= r)
  123.             return 0;
  124.  
  125.         if (vertice[num].unPushed) {
  126.             makePush(num);
  127.         }
  128.  
  129.         if (vertice[num].left == l && vertice[num].right == r)
  130.             return vertice[num].sum;
  131.         ll mid = (vertice[num].left + vertice[num].right) / 2;
  132.         return (askSum(2 * num + 1, l, min(mid, r)) + askSum(2 * num + 2, max(mid, l), r) + 3*M) % M;
  133.     }
  134.  
  135.  
  136. public:
  137.  
  138.     PolynomialSegmentTree(int n) {
  139.         length = 4 * n;
  140.         vertice.resize(length);
  141.         build(0, 0, n);
  142.     }
  143.  
  144.     void add(ll l, ll r) {
  145.         add(0, l, r, 1, -(2 * l - 3), ((l - 1)*(l - 2)) % M);
  146.     }
  147.  
  148.     ll ask(ll l, ll r) {
  149.         return askSum(0, l, r);
  150.     }
  151.  
  152.     void print() {
  153.         for (int i = 0; i < length; ++i)
  154.             vertice[i].print();
  155.     }
  156.  
  157. };
  158.  
  159. int main() {
  160. ofstream fout("output.txt");
  161.     /*int nn, qq;
  162.     nn = 20000;
  163.     qq = 50;
  164.  
  165.     fout << nn << " " << qq << "\n";
  166.    
  167.     for (int i = 0; i < qq; ++i) {
  168.         int a = rand() % nn + 1;
  169.         int b = rand() % nn + 1;
  170.         if (a > b)
  171.             swap(a, b);
  172.         fout << rand() % 2 + 1 << " " << a << " " << b << "\n";
  173.     }
  174. return 0;*/
  175.  
  176.     int n, q;
  177.     cin >> n >> q;
  178.  
  179.     PolynomialSegmentTree cTree(n);
  180.  
  181.     for (ll i = 0; i < q; ++i) {
  182.     //  cTree.print();
  183.         ll type, x, y;
  184.         cin >> type >> x >> y;
  185.     //  cerr << "azazazazdfjwfijfwifrjfiejgiojrgijreifjrgfiergjergrgtrgergerggeqgrgregerg\n";
  186.         if (type == 1) {
  187.             cTree.add(x - 1, y);
  188.         }
  189.         if (type == 2) {
  190.             fout << cTree.ask(x - 1, y) << "\n";
  191.         }
  192.  
  193.     }
  194.  
  195.     //system("pause");
  196.  
  197.     return 0;
  198. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement