mr_dot_convict

19C-Deletion-of-repetitions-codeforces-mr.convict

Jul 18th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.30 KB | None | 0 0
  1.  
  2. // Hack it and have it ;) //
  3. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  4.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  5.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  6.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  7.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  8. When I wrote this, only God and I understood what I was doing
  9.  ** * * * * * * * Now, only God knows * * * * * * */
  10. #include      <bits/stdc++.h>
  11. #include      <ext/pb_ds/assoc_container.hpp>
  12. #include      <ext/pb_ds/tree_policy.hpp>
  13. using namespace std;
  14. using namespace __gnu_pbds;
  15. // #pragma GCC   optimize ("Ofast")
  16. // #pragma GCC   optimize ("unroll-loops")
  17. // #pragma GCC   target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  18.  
  19. #define IOS   ios_base::sync_with_stdio(false); cin.tie (nullptr)
  20. #define PREC  cout.precision (10); cout << fixed
  21. #define x     first
  22. #define y     second
  23. #define bg(x) " [ " << #x << " : " << (x) << " ] "
  24. #define un(x) sort(x.begin(), x.end()), \
  25.               x.erase(unique(x.begin(), x.end()), x.end())
  26. using   ll  = long long;
  27. using   ull = unsigned long long;
  28. using   ff  = long double;
  29. using   pii = pair<int,int>;
  30. using   pil = pair<int,ll>;
  31. typedef tree
  32. < int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
  33. ordered_set;
  34.  
  35. struct chash {
  36.    int operator()(pii x) const { return x.x*31 + x.y; }
  37. };
  38. gp_hash_table <pii, int, chash> mp;
  39.  
  40. seed_seq seq{
  41.    (uint64_t) chrono::duration_cast<chrono::nanoseconds>
  42.       (chrono::high_resolution_clock::now().time_since_epoch()).count(),
  43.       (uint64_t) __builtin_ia32_rdtsc(),
  44.       (uint64_t) (uintptr_t) make_unique<char>().get()
  45. };
  46. mt19937 rng(seq); //uniform_int_distribution<int> (l, h)(rng); //[low, high]
  47.  
  48. #define debug(args...) { \
  49.    /* WARNING : do NOT compile this debug func calls with following flags: // \
  50.     * // -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2*/ \
  51.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  52.    stringstream _ss(_s); \
  53.    istream_iterator<string> _it(_ss); err(_it, args); \
  54. }
  55. void err(istream_iterator<string> it) {
  56.    it->empty(); cerr << " (Line : " << __LINE__ << ")" << '\n';
  57. }
  58. template<typename T, typename... Args>
  59. void err(istream_iterator<string> it, T a, Args... args) {
  60.    cerr << fixed << setprecision(15)
  61.       << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  62.    err(++it, args...);
  63. }
  64. /*****************************************************************************/
  65.  
  66. struct polyhash {
  67.    using ull = unsigned long long;
  68.    static const int Mod = (int)1e9 + 123;
  69.    static vector <int> pow_int;
  70.    static vector <ull> pow_ull;
  71.    static int p; // take p such that a[i] < p < Mod, gcd(p, Mod) = 1
  72.    static int gen_base (const int l, const int r) {
  73.       int base = uniform_int_distribution<int>(l + 1, r) (rng);
  74.       return base % 2 == 0 ? base - 1 : base;
  75.    }
  76.    static void calc_pow(int mx_len) {
  77.       while ((int)pow_int.size() <= mx_len) { // calc powers
  78.          pow_int.push_back(int(1ll * pow_int.back() * p % Mod));
  79.          pow_ull.push_back(pow_ull.back() * p);
  80.       }
  81.    }
  82.    const int sz;
  83.  
  84.    vector <int> s;
  85.    vector <int> pref_int;
  86.    vector <ull> pref_ull;
  87.  
  88.    void encode(const vector <int> &st) {
  89.       s.assign(sz, 0);
  90.       for (int i = 0; i < sz; ++i) s[i] = st[i];
  91.    }
  92.  
  93.    polyhash (const vector <int> &st) : sz((int)st.size())
  94.    {
  95.       encode(st);
  96.       pref_int.assign(sz + 1u, 0);
  97.       pref_ull.assign(sz + 1u, 0);
  98.       assert(p < Mod);
  99.  
  100.       calc_pow(sz + 1);
  101.  
  102.       for (int i = 0; i < sz; ++i) {
  103.          assert(p > s[i]);
  104.          pref_int[i] = int(1ll*s[i]*pow_int[i] % Mod);
  105.          pref_int[i] = (pref_int[i] + (i > 0 ? pref_int[i - 1] : 0)) % Mod;
  106.          pref_ull[i] = s[i]*pow_ull[i] + (i > 0 ? pref_ull[i - 1] : 0);
  107.       }
  108.    }
  109.  
  110.    inline pair <int, ull> operator()
  111.       (const int pos, const int len, const int mx_len = -1) const
  112.       {
  113.          int hash_int = pref_int[pos + len - 1];
  114.          ull hash_ull = pref_ull[pos + len - 1];
  115.          if (pos != 0) {
  116.             hash_int = (hash_int - pref_int[pos - 1] + Mod) % Mod;
  117.             hash_ull = hash_ull - pref_ull[pos - 1];
  118.          }
  119.          if (mx_len != -1) { // for direct comparison between prefixes
  120.             //else multiply with opposite powers
  121.             assert (mx_len < (int)pow_int.size());
  122.             hash_int = int(1ll*hash_int*pow_int[mx_len - (pos+len-1)] % Mod);
  123.             hash_ull *= pow_ull[mx_len - (pos+len-1)];
  124.          }
  125.          return make_pair(hash_int, hash_ull);
  126.       }
  127.    //string a; polyhash hash_a(a); if (hash_a(i, len, sz) == hash_b(j, len, sz))
  128.    //indexing from 0, len >= 1
  129. };
  130.  
  131. int polyhash::p = polyhash::gen_base((int)1e9, polyhash::Mod);
  132. vector <int> polyhash::pow_int{1};
  133. vector <ull> polyhash::pow_ull{1};
  134. // int polyhash::p = 31; // 31 for [a ... z], 53 for [a..z, A..Z]
  135.  
  136. const int N = (int)2e5 + 10;
  137. int n;
  138. vector <int> str;
  139. map <int, int> idx;
  140. vector <vector <int>> adj;
  141. int cnt = 0;
  142.  
  143. void create_idx(int x) {
  144.    if (idx.find(x) == idx.end())
  145.       idx[x] = cnt++;
  146. }
  147.  
  148. void solve() {
  149.    polyhash hash(str);
  150.  
  151.    for (int i = 0; i < n; ++i) {
  152.       create_idx(str[i]);
  153.    }
  154.    adj.assign(cnt, vector <int>());
  155.    for (int i = 0; i < n; ++i) {
  156.       adj[idx[str[i]]].push_back(i);
  157.    }
  158.  
  159.    vector <pair <pii, int>> store;
  160.    for (int cc = 0; cc < cnt; ++cc) {
  161.       sort (adj[cc].begin(), adj[cc].end());
  162.       for (int ii = 0; ii < (int)adj[cc].size(); ++ii) {
  163.          for (int jj = ii + 1; jj < (int)adj[cc].size(); ++jj) {
  164.             int i = adj[cc][ii], j = adj[cc][jj];
  165.             int len = j - i;
  166.             if (j + len > n) continue;
  167.             if (hash(i, len, n) == hash(j, len, n)) {
  168.                store.emplace_back(make_pair(len, j), i);
  169.             }
  170.          }
  171.       }
  172.    }
  173.    sort (store.begin(), store.end());
  174.  
  175.    int cur_l = 0;
  176.    for (int i = 0; i < (int)store.size(); ++i) {
  177.       if (store[i].y >= cur_l)
  178.          cur_l = store[i].x.y;
  179.    }
  180.    cout << n - cur_l << '\n';
  181.    for (int i = cur_l; i < n; ++i) {
  182.       cout << str[i] << ' ';
  183.    }
  184.    cout << '\n';
  185. }
  186.  
  187. void read() {
  188.    cin >> n;
  189.    str.clear();
  190.    for (int i = 0; i < n; ++i) {
  191.       int foo;
  192.       cin >> foo;
  193.       str.push_back(foo);
  194.    }
  195. }
  196.  
  197. signed main() {
  198.    IOS; PREC;
  199.    read(), solve();
  200.  
  201.    return EXIT_SUCCESS;
  202. }
Add Comment
Please, Sign In to add comment