Tuesday, September 24, 2019

[Codemarshal] D. Has Anyone Seen Harry?

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : D. Has Anyone Seen Harry?
Source            : Codemarshal
                    City University IUPC 2017
Category          : String, Data Structure
Algorithm         : Hashing, Segment Tree
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. static const int maxn = 2e5 + 5;  
  6. static const long long mod = 1e9 + 123;  
  7.   
  8. struct SegmentTree  
  9. {  
  10.       long long x;  
  11.       unsigned long long y;  
  12.       SegmentTree(long long x = 0, unsigned long long y = 0) : x(x), y(y) {}  
  13.   
  14.       void assignLeaf(long long xx, unsigned long long yy)  
  15.       {  
  16.             x = xx;  
  17.             y = yy;  
  18.       }  
  19.       void marge(const SegmentTree &lchild, const SegmentTree &rchild)  
  20.       {  
  21.             x = (lchild.x + rchild.x) % mod;  
  22.             y = lchild.y + rchild.y;  
  23.       }  
  24. } Tree[maxn * 4];  
  25.   
  26. void update(int node, int a, int b, int pos, long long x, unsigned long long y)  
  27. {  
  28.       if (a > pos or b < pos) return;  
  29.       if (a >= pos and b <= pos)  
  30.       {  
  31.             Tree[node].assignLeaf(x, y);  
  32.             return;  
  33.       }  
  34.       int lft = node * 2;  
  35.       int rgt = lft + 1;  
  36.       int mid = (a + b) / 2;  
  37.       update(lft, a, mid, pos, x, y);  
  38.       update(rgt, mid + 1, b, pos, x, y);  
  39.       Tree[node].marge(Tree[lft], Tree[rgt]);  
  40. }  
  41.   
  42. SegmentTree query(int node, int a, int b, int i, int j)  
  43. {  
  44.       if (a > j or b < i) return SegmentTree();  
  45.       if (a >= i and b <= j) return Tree[node];  
  46.       int lft = node * 2;  
  47.       int rgt = lft + 1;  
  48.       int mid = (a + b) / 2;  
  49.       SegmentTree p = query(lft, a, mid, i, j);  
  50.       SegmentTree q = query(rgt, mid + 1, b, i, j);  
  51.       SegmentTree res;  
  52.       res.marge(p, q);  
  53.       return res;  
  54. }  
  55.   
  56. int gen_base(const int before, const int after)  
  57. {  
  58.       auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();  
  59.       mt19937 mt_rand(seed);  
  60.       int base = uniform_int_distribution <int> (before, after)(mt_rand);  
  61.       return base % 2 == 0 ? base - 1 : base;  
  62. }  
  63.   
  64. long long pow1[maxn];  
  65. unsigned long long pow2[maxn];  
  66. int base;  
  67.   
  68. void preCalc()  
  69. {  
  70.       pow1[0] = 1;  
  71.       pow2[0] = 1;  
  72.       for (int i = 1; i < maxn; i++)  
  73.       {  
  74.             pow1[i] = (1LL * base * pow1[i - 1]) % mod;  
  75.             pow2[i] = pow2[i - 1] * base;  
  76.       }  
  77. }  
  78.   
  79. signed main()  
  80. {  
  81.       ios_base::sync_with_stdio(false);  
  82.       cin.tie(nullptr);  
  83.       cout.tie(nullptr);  
  84.   
  85. //      #ifndef ONLINE_JUDGE  
  86. //            freopen("in.txt", "r", stdin);  
  87. //      #endif // ONLINE_JUDGE  
  88.   
  89.   
  90.       //base = 257;  
  91.       base = gen_base(256, mod);  
  92.       preCalc();  
  93.   
  94.       int tc;  
  95.       cin >> tc;  
  96.       for (int tcase = 1; tcase <= tc; tcase++)  
  97.       {  
  98.             int n, q;  
  99.             cin >> n >> q;  
  100.             string s;  
  101.             cin >> s;  
  102.             for (int i = 0; i < n; i++)  
  103.             {  
  104.                   long long x = (1LL * s[i] * pow1[i]) % mod;  
  105.                   long long y = s[i] * pow2[i];  
  106.                   update(1, 1, n, i + 1, x, y);  
  107.             }  
  108.             cout << "Case " << tcase << ":\n";  
  109.             int mxPow = n;  
  110.             while (q--)  
  111.             {  
  112.                   int type;  
  113.                   cin >> type;  
  114.                   if (type == 0)  
  115.                   {  
  116.                         int pos;  
  117.                         cin >> pos;  
  118.                         if (s[pos] == '1') s[pos] = '0';  
  119.                         else s[pos] = '1';  
  120.                         long long x = (1LL * s[pos] * pow1[pos]) % mod;  
  121.                         long long y = s[pos] * pow2[pos];  
  122.                         update(1, 1, n, pos + 1, x, y);  
  123.                   }  
  124.                   else  
  125.                   {  
  126.                         int i, j, len;  
  127.                         cin >> i >> j >> len;  
  128.                         SegmentTree tree1;  
  129.                         tree1 = query(1, 1, n, i + 1, i + len);  
  130.                         if (tree1.x < 0) tree1.x += mod;  
  131.                         if (mxPow != 0)  
  132.                         {  
  133.                               tree1.x = tree1.x * pow1[mxPow - (i + len - 1)] % mod;  
  134.                               tree1.y = tree1.y * pow2[mxPow - (i + len - 1)];  
  135.                         }  
  136.                         SegmentTree tree2;  
  137.                         tree2 = query(1, 1, n, j + 1, j + len);  
  138.                         if (tree2.x < 0) tree2.x += mod;  
  139.                         if (mxPow != 0)  
  140.                         {  
  141.                               tree2.x = tree2.x * pow1[mxPow - (j + len - 1)] % mod;  
  142.                               tree2.y = tree2.y * pow2[mxPow - (j + len - 1)];  
  143.                         }  
  144.                         if (tree1.x == tree2.x and tree1.y == tree2.y) cout << 1 << '\n';
  145.                         else cout << 0 << '\n';  
  146.                   }  
  147.             }  
  148.       }  
  149. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.