Advertisement
Guest User

Untitled

a guest
Feb 19th, 2018
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.93 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6.  
  7. const int MOD = 997;
  8.  
  9. class arbint
  10. {
  11. public:
  12.     arbint(int n, int k)
  13.     {
  14.         this->n = n;
  15.         this->k = k;
  16.         v.resize((1 << (int)ceil(log2(n) + 1)), 1);
  17.         edges.resize(n+1, k*k);
  18.         Build(1, 1, n);
  19.    //     for(int i = 1; i < v.size(); ++i)
  20.      //       cout << i << " " << v[i] << "\n";
  21.     }
  22.     void AddEdges(int st, int nr)
  23.     {
  24.         edges[st] = k * k + nr;
  25.         Update(1, st, st+1);
  26.     }
  27.     int Query(int st, int dr)
  28.     {
  29.         return Query(1, 1, n, st, dr);
  30.     }
  31. private:
  32.     void Build(int nod, int st, int dr)
  33.     {
  34.         if(st == dr)
  35.             return;
  36.         if(st + 1 == dr)
  37.         {
  38.             v[nod] = edges[st];
  39.             return;
  40.         }
  41.         int mid = (st + dr) / 2;
  42.         int nodSt = 2 * nod, nodDr = 2 * nod + 1;
  43.         Build(nodSt, st, mid);
  44.         if(mid+1 > n)
  45.         {
  46.             v[nod] = v[nodSt];
  47.             return;
  48.         }
  49.         Build(nodDr, mid+1, dr);
  50.         v[nod] = (v[nodSt] * v[nodDr] * k * k) % MOD;
  51.     }
  52.     void Update(int nod, int st, int dr)
  53.     {
  54.         if(st == dr)
  55.             return;
  56.         if(st + 1 == dr)
  57.         {
  58.             v[nod] = edges[st];
  59.             return;
  60.         }
  61.         int mid = (st + dr) / 2;
  62.         int nodSt = 2 * nod, nodDr = 2 * nod + 1;
  63.         if(nod <= mid)
  64.             Update(nodSt, st, mid);
  65.         else
  66.             Update(nodDr, mid+1, dr);
  67.         v[nod] = (v[nodSt] * v[nodDr] * edges[mid]) % MOD;
  68.     }
  69.     int Query(int nod, int st, int dr, int start, int stop)
  70.     {
  71.         if(start <= st && stop >= dr)
  72.             return v[nod];
  73.         int ret = 1;
  74.         int mid = (st + dr) / 2;
  75.         int nodSt = 2 * nod, nodDr = 2 * nod + 1;
  76.         if(start <= mid)
  77.             ret *= Query(nodSt, st, mid, start, stop);
  78.         if(stop > mid)
  79.             ret *= Query(nodDr, mid+1, dr, start, stop);
  80.         if(start <= mid && stop > mid)
  81.             ret = ret * edges[mid];
  82.         ret %= MOD;
  83.         return ret;
  84.     }
  85.     int n, k;
  86.     vector<int> v;
  87.     vector<int> edges; //nr muchii de la i la i+1
  88. };
  89.  
  90. int main()
  91. {
  92.     ifstream in("namlei.in");
  93.     ofstream out("namlei.out");
  94.     int n, K, x, y;
  95.     in >> n >> K;
  96.     n++;
  97.     vector<vector<vector<int> > > edges(n+1, vector<vector<int> >(K+1, vector<int>(K+1, 1)));
  98.     arbint arb(n, K);
  99.     in >> x >> y;
  100.     for(int i = 1; i < n; ++i)
  101.     {
  102.         int cnt, j, k;
  103.         in >> cnt >> j >> k;
  104.         arb.AddEdges(i, cnt);
  105.         edges[i][j+1][k+1]++;
  106.   //      cout << i << " " << j+1 << " " << k+1 << "\n";
  107.         for(int w = 1; w < cnt; ++w)
  108.         {
  109.             j = (j * x + k * w * y) % K;
  110.             k = (j * w * x + k * y) % K;
  111.             edges[i][j+1][k+1]++;
  112.    //         cout << i << " " << j+1 << " " << k+1 << "\n";
  113.         }
  114.     }
  115.     char t;
  116.     while(in >> t)
  117.     {
  118.         if(t == 'U')
  119.         {
  120.             int i, cnt, j, k;
  121.             in >> i >> cnt >> j >> k;
  122.             arb.AddEdges(i, cnt);
  123.             edges[i][j+1][k+1]++;
  124.             for(int w = 1; w < cnt; ++w)
  125.             {
  126.                 j = (j * x + k * w * y + 1) % K;
  127.                 k = (j * w * x + k * y + 1) % K;
  128.                 edges[i][j+1][k+1]++;
  129.             }
  130.         }
  131.         else
  132.         {
  133.             int i, x, j, y;
  134.             in >> i >> x >> j >> y;
  135.             i++, x++, j++, y++;
  136.             if(i + 1 == j)
  137.                 out << edges[i][x][y] << "\n";
  138.             else
  139.             {
  140.                 int a = 0, b = 0;
  141.                 for(int ob = 1; ob <= K; ++ob)
  142.                 {
  143.                     a += edges[i][x][ob];
  144.                     b += edges[j-1][ob][y];
  145.                 }
  146.                 cout << a << " " << b << "\n";
  147.                 int rasp = (a * b * arb.Query(i+1, j-1)) % MOD;
  148.                 out << rasp << "\n";
  149.             }
  150.         }
  151.     }
  152.     return 0;
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement