Alex_tz307

1354 - Palindrome. Again Palindrome -Timus(HASHING)

Nov 2nd, 2020
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.12 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. template < int MOD >
  6. class Zn {
  7.     long long value;
  8.  
  9.     public:
  10.         Zn(int value = 0) {
  11.             this -> value = ((value % MOD) + MOD) % MOD;
  12.         }
  13.  
  14.         Zn operator *(const Zn &other) const {
  15.             return (this -> value * other.value) % MOD;
  16.         }
  17.  
  18.         Zn operator +(const Zn &other) const {
  19.             return (this -> value + other.value) % MOD;
  20.         }
  21.  
  22.         Zn operator -() const {
  23.             return (MOD - this -> value) % MOD;
  24.         }
  25.  
  26.         Zn operator -(const Zn &other) const {
  27.             return (this -> value - other.value + MOD) % MOD;
  28.         }
  29.  
  30.         Zn operator ^(const unsigned int exp) const {
  31.             if(exp == 0)
  32.                 return Zn(1);
  33.             if(exp & 1)
  34.                 return (*this) * ((*this) ^ (exp - 1));
  35.             Zn ab2 = (*this) ^ (exp >> 1);
  36.             return ab2 * ab2;
  37.         }
  38.  
  39.         Zn operator /(const Zn &other) const {
  40.             return (*this) * (other ^ (unsigned int)(MOD - 2));
  41.         }
  42.  
  43.         operator int() const {
  44.             return this -> value;
  45.         }
  46. };
  47.  
  48. const int P1 = 1000000007;
  49. const int P2 = 1000000009;
  50.  
  51. struct Hash {
  52.     Zn<P1> rest1;
  53.     Zn<P2> rest2;
  54.     int Size;
  55.  
  56.     Hash() {
  57.         rest1 = 0;
  58.         rest2 = 0;
  59.         Size = 0;
  60.     }
  61. };
  62.  
  63. const int MAX_N = 100000;
  64. const int BASE = 253;
  65.  
  66. Zn<P1> Bases1[MAX_N + 1];
  67. Zn<P2> Bases2[MAX_N + 1];
  68.  
  69. void init() {
  70.     int i;
  71.     Bases1[0] = 1;
  72.     Bases2[0] = 1;
  73.     for(i = 1; i <= MAX_N; ++i) {
  74.         Bases1[i] = Bases1[i - 1] * Zn<P1>(BASE);
  75.         Bases2[i] = Bases2[i - 1] * Zn<P2>(BASE);
  76.     }
  77. }
  78.  
  79. Hash append(Hash s, char l) {
  80.     s.rest1 = s.rest1 * Zn<P1>(BASE) + Zn<P1>(l);
  81.     s.rest2 = s.rest2 * Zn<P2>(BASE) + Zn<P2>(l);
  82.     ++s.Size;
  83.     return s;
  84. }
  85.  
  86. Hash prepend(char l, Hash s) {
  87.     s.rest1 = Zn<P1>(l) * Bases1[s.Size] + s.rest1;
  88.     s.rest2 = Zn<P2>(l) * Bases2[s.Size] + s.rest2;
  89.     ++s.Size;
  90.     return s;
  91. }
  92.  
  93. Hash join(Hash s1, Hash s2) {
  94.     s1.rest1 = s1.rest1 * Bases1[s2.Size] + s2.rest1;
  95.     s1.rest2 = s1.rest2 * Bases2[s2.Size] + s2.rest2;
  96.     s1.Size += s2.Size;
  97.     return s1;
  98. }
  99.  
  100. bool equals(Hash s1, Hash s2) {
  101.     return s1.rest1 == s2.rest1 && s1.rest2 == s2.rest2 && s1.Size == s2.Size;
  102. }
  103.  
  104. Hash eraseFromEnd(Hash s, char l) {
  105.     s.rest1 = (s.rest1 - Zn<P1>(l)) / Zn<P1>(BASE);
  106.     s.rest2 = (s.rest2 - Zn<P2>(l)) / Zn<P2>(BASE);
  107.     --s.Size;
  108.     return s;
  109. }
  110.  
  111. Hash eraseFromBeginning(char l, Hash s) {
  112.     s.rest1 = s.rest1 - Zn<P1>(l) * Bases1[s.Size - 1];
  113.     s.rest2 = s.rest2 - Zn<P2>(l) * Bases2[s.Size - 1];
  114.     --s.Size;
  115.     return s;
  116. }
  117.  
  118. int main() {
  119.     ios_base::sync_with_stdio(false);
  120.     cin.tie(nullptr);
  121.     cout.tie(nullptr);
  122.     init();
  123.     string s;
  124.     cin >> s;
  125.     int N = s.size(), sol = N;
  126.     Hash normal, invers;
  127.     for(int i = N - 1; i > 0; --i) {
  128.         normal = prepend(s[i], normal);
  129.         invers = append(invers, s[i]);
  130.         if(equals(invers, normal))
  131.             sol = i;
  132.     }
  133.     for(int i = sol - 1; i >= 0; --i)
  134.         s.push_back(s[i]);
  135.     cout << s;
  136. }
  137.  
Advertisement
Add Comment
Please, Sign In to add comment