[关闭]
@jason-fan 2021-04-26T14:25:27.000000Z 字数 17027 阅读 178

哈希 Hash - 例题 AC CODE

CODE


BZOJ1567

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int N = 55;
  5. const int mod = 1019260817;
  6. const int bs = 10007;
  7. int n, a[N][N], b[N][N];
  8. set<ll> vs[N];
  9. ll row[N][N], hsh[N][N][N], pw[N];
  10. ll calc(int c, int l, int r) {
  11. return (row[c][r] - row[c][l - 1] * pw[r - l + 1] % mod + mod) % mod;
  12. }
  13. void inithash(int(*a)[N]) {
  14. pw[0] = 1; for (int i = 1; i <= n; ++i) pw[i] = pw[i - 1] * bs % mod;
  15. for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j)
  16. row[i][j] = ((ll)row[i][j - 1] * bs + a[i][j]) % mod;
  17. for (int i = 1; i <= n; ++i) {
  18. for (int j = 1; j <= n; ++j) { // (i,j)
  19. for (int k = 1; max(i, j) + k - 1 <= n; ++k) {
  20. hsh[i][j][k] = 0;
  21. for (int p = 1; p <= k; ++p)
  22. hsh[i][j][k] = (hsh[i][j][k] * pw[k] + calc(i + p - 1, j, j + k - 1)) % mod;
  23. }
  24. }
  25. }
  26. }
  27. int main() {
  28. scanf("%d", &n);
  29. for (int i = 1;i <= n;++i) for (int j = 1;j <= n;++j) scanf("%d", &a[i][j]);
  30. for (int i = 1;i <= n;++i) for (int j = 1;j <= n;++j) scanf("%d", &b[i][j]);
  31. inithash(a);
  32. for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j)
  33. for (int k = 1; min(i, j) + k - 1 <= n; ++k) vs[k].insert(hsh[i][j][k]);
  34. inithash(b);
  35. for (int k = n; k >= 1; --k)
  36. for (int i = 1; i + k - 1 <= n; ++i)
  37. for (int j = 1; j + k - 1 <= n; ++j) if (vs[k].count(hsh[i][j][k]))
  38. {printf("%d\n", k); return 0;}
  39. puts("0");
  40. return 0;
  41. }

BZOJ4337

  1. #include <bits/stdc++.h>
  2. template<typename _Tp>
  3. inline void red(_Tp& x) {
  4. x = 0;bool fg = 0;char ch = getchar();
  5. while (ch < '0' || ch>'9') { if (ch == '-') fg ^= 1;ch = getchar(); }
  6. while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();
  7. if (fg) x = -x;
  8. }
  9. template <typename _Tp, typename... Args>void red(_Tp& t, Args &... args) { red(t);red(args...); }
  10. using namespace std;
  11. typedef long long ll;
  12. const int mod = 1019260817;
  13. const int N = 110;
  14. const int base = 97;
  15. int head[N], fa[N], pnt[N], nxt[N], E;
  16. int m, n, siz[N], rt1, rt2;
  17. ll hah[N], pw[N];
  18. pair<ll, ll> Hash[N];
  19. vector<int> e[N];
  20. void init() {
  21. for (int i = 1;i <= n;++i) e[i].clear();
  22. rt1 = rt2 = -1;
  23. }
  24. void dfs(int u, int f = 0, int dep = 1) {
  25. siz[u] = 1; hah[u] = dep;
  26. for (int i = 0, v;i < e[u].size();++i) {
  27. v = e[u][i]; if (v == f) continue;
  28. dfs(v, u, dep + 1);
  29. siz[u] += siz[v];
  30. }
  31. sort(e[u].begin(), e[u].end(), [](int x, int y) {
  32. return hah[x] < hah[y];
  33. });
  34. for (int i = 0, v;i < e[u].size();++i) {
  35. v = e[u][i]; if (v == f) continue;
  36. hah[u] = (hah[u] * pw[siz[v]] + hah[v]) % mod;
  37. }
  38. }
  39. void getroot(int u, int f = 0) {
  40. assert(u != 0);
  41. siz[u] = 1; int mxsiz = 0;
  42. for (int i = 0, v;i < e[u].size();++i) {
  43. v = e[u][i]; if (v == f) continue;
  44. getroot(v, u); siz[u] += siz[v];
  45. mxsiz = max(mxsiz, siz[v]);
  46. }
  47. mxsiz = max(mxsiz, n - siz[u]);
  48. if (mxsiz <= n / 2) {
  49. if (rt1 == -1) rt1 = u;
  50. else rt2 = u;
  51. }
  52. }
  53. int main() {
  54. red(m);
  55. pw[0] = 1; for (int i = 1;i < N;++i) pw[i] = pw[i - 1] * base % mod;
  56. for (int t = 1;t <= m;++t) {
  57. init(); red(n);
  58. for (int i = 1;i <= n;++i) {
  59. red(fa[i]);
  60. if (fa[i] != 0) {
  61. e[fa[i]].push_back(i);
  62. e[i].push_back(fa[i]);
  63. }
  64. }
  65. getroot(1);
  66. dfs(rt1); Hash[t].first = hah[rt1];
  67. if (rt2 == -1) Hash[t].second = hah[rt1];
  68. else {
  69. dfs(rt2); Hash[t].second = hah[rt2];
  70. if (Hash[t].first > Hash[t].second)
  71. swap(Hash[t].first, Hash[t].second);
  72. }
  73. }
  74. for (int t = 1;t <= m;++t) {
  75. for (int i = 1;i <= m;++i) {
  76. if (Hash[t] == Hash[i]) {
  77. printf("%d\n", i);
  78. break;
  79. }
  80. }
  81. }
  82. return 0;
  83. }

SPOJ-LCS2 luogu

  1. #include <bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. using namespace std;
  5. typedef long long ll;
  6. typedef pair<ll, ll> pll;
  7. typedef unsigned long long ull;
  8. const int N = 100010;
  9. namespace strhash {
  10. const int p1 = 1019260817;
  11. const int p2 = 1019260819;
  12. const int bs = 233;
  13. pll pw[N], f[N];
  14. pll operator*(pll a, ll b) { return pll(a.fi * b % p1, a.se * b % p2); }
  15. pll operator+(pll a, ll b) { return pll((a.fi + b) % p1, (a.se + b) % p2); }
  16. pll operator-(pll a, pll b) { return pll((a.fi - b.fi + p1) % p1, (a.se - b.se + p2) % p2); }
  17. pll operator*(pll a, pll b) { return pll(a.fi * b.fi % p1, a.se * b.se % p2); }
  18. void init(char* S, int n) {
  19. pw[0] = pll{ 1,1 };
  20. for (int i = 1;i <= n;++i) {
  21. f[i] = (f[i - 1] * bs + (S[i] - 'a' + 1));
  22. pw[i] = pw[i - 1] * bs;
  23. }
  24. }
  25. ull gethash(int l, int r) {
  26. pll a = f[r] - f[l - 1] * pw[r - l + 1];
  27. return (ull)a.fi << 32 | (ull)a.se;
  28. }
  29. }
  30. using strhash::init;using strhash::gethash;
  31. int n, len[10];
  32. char str[10][N];
  33. struct my_hash {
  34. static ull mix64(ull x) {
  35. x += 0x9e3779b97f4a7c15;
  36. x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
  37. x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
  38. return x ^ (x >> 31);
  39. }
  40. size_t operator()(ull x) const { return mix64(x); }
  41. };
  42. unordered_set<ull, my_hash> S1, S2;
  43. bool check(int l) {
  44. init(str[0], len[0]);
  45. S1.clear();S2.clear();
  46. for (int i = 1;i + l - 1 <= len[0];++i) {
  47. S1.insert(gethash(i, i + l - 1));
  48. }
  49. for (int i = 1;i < n;++i) {
  50. if (S1.empty()) return false;
  51. init(str[i], len[i]);
  52. for (int j = 1;j + l - 1 <= len[i];++j) {
  53. ull mask = gethash(j, j + l - 1);
  54. if (S1.find(mask) != S1.end()) {
  55. S2.insert(mask);
  56. S1.erase(mask);
  57. }
  58. }
  59. S1.clear();swap(S1, S2);
  60. }
  61. return !S1.empty();
  62. }
  63. int main() {
  64. while (scanf("%s", str[n] + 1) != EOF) {
  65. len[n] = strlen(str[n] + 1);
  66. ++n;
  67. }
  68. int L = 0, R = *min_element(len, len + n), M, ans;
  69. while (L <= R) {
  70. M = (L + R) >> 1;
  71. if (check(M)) ans = M, L = M + 1;
  72. else R = M - 1;
  73. }
  74. cout << ans << endl;
  75. return 0;
  76. }

BZOJ3198

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int N = 100010;
  5. const int p1 = 1019260817;
  6. const int p2 = 1019260819;
  7. const int bs = 125641;
  8. int a[N][6], n, k, C[7][7];
  9. struct Hash_map {
  10. static const int MAX_SIZE = 200010, M = 1627361;
  11. struct data {
  12. int nxt;
  13. ll key, value;
  14. } e[MAX_SIZE];
  15. int head[M], size;
  16. inline int f(ll key) { return key % M; } // 哈希函数
  17. ll& operator[](const ll& key) {
  18. int ky = f(key);
  19. for (int i = head[ky]; i != -1; i = e[i].nxt)
  20. if (e[i].key == key) return e[i].value;
  21. return e[++size] = data{ head[ky], key, 0 }, head[ky] = size, e[size].value;
  22. }
  23. void clear() {
  24. memset(head, -1, sizeof(head));
  25. size = 0;
  26. }
  27. Hash_map() { clear(); }
  28. };
  29. Hash_map ct;
  30. ll calc(int mask) {
  31. ct.clear(); ll res = 0;
  32. for (int i = 1;i <= n;++i) {
  33. ll h1 = 0, h2 = 0;
  34. for (int p = 0;p < 6;++p) if ((mask >> p) & 1) {
  35. h1 = (h1 * bs + a[i][p]) % p1;
  36. h2 = (h2 * bs + a[i][p]) % p2;
  37. }
  38. res += ct[h1 * h2]++;
  39. }
  40. return res;
  41. }
  42. int main() {
  43. scanf("%d%d", &n, &k);
  44. for (int i = 1;i <= n;++i) for (int j = 0;j < 6;++j) scanf("%d", &a[i][j]);
  45. C[0][0] = 1;
  46. for (int i = 1;i <= 6;++i) {
  47. C[i][0] = 1;
  48. for (int j = 1;j <= i;++j) C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
  49. }
  50. ll ans = 0;
  51. for (int mask = 0;mask < (1 << 6);++mask) {
  52. int ct = 0; for (int x = mask;x;x -= x & -x) ++ct;
  53. if (ct < k) continue;
  54. ll tmp = calc(mask) * C[ct][k];
  55. if ((ct - k) & 1) ans -= tmp;
  56. else ans += tmp;
  57. }
  58. printf("%lld\n", ans);
  59. return 0;
  60. }

HDU6647 vjudge

  1. #include <bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. using namespace std;
  5. typedef long long ll;
  6. const int N = 100010;
  7. const int mod = 998244353;
  8. inline ll Mod(ll x) {return x < mod ? x : x % mod;}
  9. typedef pair<ll, ll> pll;
  10. const int p1 = 1019260817; // 双模 hash
  11. const int p2 = 1019260819;
  12. const int c = 517666;
  13. pll operator*(const pll &a, const ll &b) {return pll(a.fi * b % p1, a.se * b % p2);}
  14. pll operator*(const pll &a, const pll &b) {return pll(a.fi * b.fi % p1, a.se * b.se % p2);}
  15. pll operator+(const pll &a, const ll &b) {return pll((a.fi + b) % p1, (a.se + b) % p2);}
  16. pll operator-(const pll &a, const pll &b) {return pll((a.fi - b.fi + p1) % p1, (a.se - b.se + p2) % p2);}
  17. pll operator+(const pll &a, const pll &b) {return pll((a.fi + b.fi) % p1, (a.se + b.se) % p2);}
  18. ll fac[N], ifac[N], inv[N], pr[N];
  19. bool v[2000000];int tot;
  20. void init(int n) {
  21. fac[0] = inv[0] = inv[1] = ifac[0] = ifac[1] = 1;
  22. for (int i = 1; i <= n; ++i) fac[i] = Mod(fac[i - 1] * i);
  23. for (int i = 2; i <= n; ++i) inv[i] = Mod((mod - mod / i) * inv[mod % i]);
  24. for (int i = 2; i <= n; ++i) ifac[i] = Mod(inv[i] * ifac[i - 1]);
  25. for (int i = 2; tot < n; ++i) {
  26. if(!v[i]) pr[++tot] = i;
  27. for (int j = 1; j <= tot && pr[j] * i < 2e6; ++j) {
  28. v[i * pr[j]] = 1;
  29. if(i % pr[j] == 0) break;
  30. }
  31. }
  32. srand(time(0));
  33. random_shuffle(pr + 1, pr + tot + 1);
  34. }
  35. vector<int> e[N];
  36. int t, n, siz[N];
  37. ll f[N], g[N]; // f[u]: (以 1 为根)遍历 u 子树本质不同括号序列方案数 ; g[u] 以 u 为根
  38. pll fh[N], gh[N]; // fh[u]: (以 1 为根) u 子树哈希值 ; gh[u] 以 u 为根
  39. map<pll, int> ct[N]; // 统计 u 子树某哈希值出现次数
  40. ll qpow(ll a, ll b = mod - 2) {
  41. ll r = 1;
  42. for ( ; b; b>>=1, a = Mod(a * a)) if(b & 1) r = Mod(r * a);
  43. return r;
  44. }
  45. void dfs1(int u, int fa) {
  46. ct[u].clear();
  47. f[u] = fac[e[u].size() - (u != 1)];
  48. fh[u] = pll(0, 0); siz[u] = 1;
  49. for(auto &&v : e[u]) if(v != fa) {
  50. dfs1(v, u);
  51. fh[u] = fh[u] + fh[v] * pr[siz[v]];
  52. f[u] = Mod(f[u] * f[v]);
  53. siz[u] += siz[v];
  54. }
  55. sort(e[u].begin(), e[u].end(), [](int x, int y) {return fh[x] < fh[y];});
  56. pll pre(-1, -1); int cnt = 0;
  57. for(auto &&v : e[u]) if(v != fa) {
  58. if(pre == fh[v]) f[u] = Mod(f[u] * inv[++cnt]);
  59. else {
  60. if(pre.fi != -1) ct[u][pre] = cnt;
  61. cnt = 1, pre = fh[v];
  62. }
  63. }
  64. if(pre.fi != -1) ct[u][pre] = cnt;
  65. fh[u] = fh[u] + c;
  66. }
  67. void dfs2(int u, int fa, pll cur, ll now) {
  68. // 换根DP : cur 为父亲方向哈希值, now 为父亲方向 f
  69. g[u] = Mod(f[u] * now);
  70. gh[u] = fh[u] + cur * pr[n - siz[u]];
  71. if(u != 1) {
  72. g[u] = Mod(Mod(g[u] * e[u].size()));
  73. g[u] = Mod(g[u] * inv[++ct[u][cur]]);
  74. }
  75. for(auto &&v : e[u]) if(v != fa) {
  76. pll _cur = fh[u] - fh[v] * pr[siz[v]] + cur * pr[n - siz[u]];
  77. ll _now = Mod(Mod(g[u] * inv[e[u].size()]) * qpow(f[v]));
  78. _now = Mod(_now * ct[u][fh[v]]);
  79. dfs2(v, u, _cur, _now);
  80. }
  81. }
  82. void rmain() {
  83. scanf("%d", &n);
  84. for (int i = 1; i <= n; ++i) e[i].clear();
  85. for (int i = 1; i < n; ++i) {
  86. int u, v; scanf("%d%d", &u, &v);
  87. e[u].push_back(v); e[v].push_back(u);
  88. }
  89. dfs1(1, 0);
  90. dfs2(1, 0, pll(0, 0), 1);
  91. ct[0].clear();
  92. ll ans = 0;
  93. for (int i = 1; i <= n; ++i) {
  94. if(ct[0].count(gh[i])) continue;
  95. ct[0][gh[i]] = 1;
  96. ans = Mod(ans + g[i]);
  97. }
  98. printf("%lld\n",ans);
  99. }
  100. int main() {
  101. init(N - 1);
  102. scanf("%d", &t);
  103. while(t--) rmain();
  104. return 0;
  105. }

51Nod1553 vjudge

  1. #include <bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. #define ls (x<<1)
  5. #define rs (x<<1|1)
  6. #define mid ((l+r)>>1)
  7. using namespace std;
  8. const int N = 100010;
  9. int n,m,q; char s[N];
  10. typedef long long ll;
  11. typedef pair<ll,ll> pll;
  12. const int p1 = 1019260817; // 双模 hash
  13. const int p2 = 1019260819;
  14. const int bs = 125641; // 基数
  15. pll operator*(const pll &a,const ll &b) {return pll(a.fi * b % p1, a.se * b % p2);}
  16. pll operator*(const pll &a,const pll &b) {return pll(a.fi * b.fi % p1, a.se * b.se % p2);}
  17. pll operator+(const pll &a,const ll &b) {return pll((a.fi + b) % p1, (a.se + b) % p2);}
  18. pll operator-(const pll &a,const pll &b) {return pll((a.fi - b.fi + p1) % p1, (a.se - b.se + p2) % p2);}
  19. pll operator+(const pll &a,const pll &b) {return pll((a.fi + b.fi) % p1, (a.se + b.se) % p2);}
  20. pll pw[N],pws[N]; // pw[i] = bs ^ i
  21. void init(int n) {
  22. pw[0] = {0, 0};
  23. for (int i = 1; i <= n; ++i) pw[i] = pw[i - 1] * bs;
  24. }
  25. struct dat {
  26. pll f; // 哈希值
  27. int len; // 串长
  28. dat() { f = {0, 0}; len = 0; }
  29. dat(const pll &_f,const int &_len) { f = _f; len = _len; }
  30. };
  31. dat operator*(const dat &a,const dat &b) {
  32. return dat(a.f * pw[b.len] + b.f, a.len + b.len);
  33. }
  34. dat D[N<<2]; int tag[N<<2];
  35. ostream &operator<<(ostream &out,const dat &a) {
  36. return out<<"("<<a.f.first<<", "<<a.f.second<<", l="<<a.len<<") ";
  37. }
  38. void pushup(int x) {D[x]=D[ls]*D[rs];}
  39. void build(int l=1,int r=n,int x=1) {
  40. tag[x]=-1;
  41. if(l==r) {D[x]=dat({s[l]-'0',s[l]-'0'},1);return ;}
  42. build(l,mid,ls);build(mid+1,r,rs);
  43. pushup(x);
  44. }
  45. void seteq(int x,int vl) { tag[x]=vl; D[x].f=pws[D[x].len-1]*vl; }
  46. void pushdown(int x) {
  47. if(tag[x]!=-1) {
  48. seteq(ls,tag[x]); seteq(rs,tag[x]);
  49. tag[x]=-1;
  50. }
  51. }
  52. void modify(int L,int R,int vl,int l=1,int r=n,int x=1) {
  53. if(L<=l&&r<=R) return seteq(x,vl);
  54. pushdown(x);
  55. if(L<=mid) modify(L,R,vl,l,mid,ls);
  56. if(R>mid) modify(L,R,vl,mid+1,r,rs);
  57. pushup(x);
  58. }
  59. dat query(int L,int R,int l=1,int r=n,int x=1) {
  60. if(L>R) return dat();
  61. if(L<=l&&r<=R) return D[x];
  62. pushdown(x); dat ret;
  63. if(L<=mid) ret=query(L,R,l,mid,ls);
  64. if(R>mid) ret=ret*query(L,R,mid+1,r,rs);
  65. return ret;
  66. }
  67. int main() {
  68. scanf("%d%d%d",&n,&m,&q);q+=m;
  69. scanf("%s",s+1);
  70. pws[0]=pw[0]={1,1};
  71. for(int i=1;i<=n;++i) {
  72. pw[i]=pw[i-1]*bs;
  73. pws[i]=pws[i-1]+pw[i];
  74. }
  75. build();
  76. while(q--) {
  77. int op,l,r,x;
  78. scanf("%d%d%d%d",&op,&l,&r,&x);
  79. if(op==1) {
  80. modify(l,r,x);
  81. }else {
  82. dat a=query(l+x,r),b=query(l,r-x);
  83. // printf("[%d,%d] [%d,%d]\n",l+x,r,l,r-x);
  84. // cerr<<a<<" "<<b<<endl;
  85. if(a.f==b.f) puts("YES");
  86. else puts("NO");
  87. }
  88. }
  89. return 0;
  90. }

51Nod1863 vjudge

  1. #include <bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. template<typename _Tp>
  5. inline void read(_Tp& x) {
  6. x = 0;bool fg = 0;char ch = getchar();
  7. while (ch < '0' || ch>'9') { if (ch == '-') fg ^= 1;ch = getchar(); }
  8. while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();
  9. if (fg) x = -x;
  10. }
  11. template<typename _Tp, typename... Args>void read(_Tp& t, Args &... args) { read(t);read(args...); }
  12. using namespace std;
  13. typedef long long ll;
  14. const int N = 100010;
  15. const int M = 500010;
  16. int head[N], pnt[M << 1], nxt[M << 1], E;
  17. int n, m, P[N], PP[N], w[N];
  18. void adde(int u, int v) {
  19. E++;pnt[E] = v;nxt[E] = head[u];head[u] = E;
  20. }
  21. namespace seq_Hash {
  22. typedef long long ll;
  23. typedef pair<ll, ll> pll;
  24. const int p1 = 1019260817;
  25. const int p2 = 1019260819;
  26. const int bs = 10007;
  27. pll operator*(const pll& a, const ll& b) { return pll(a.fi * b % p1, a.se * b % p2); }
  28. pll operator*(const pll& a, const pll& b) { return pll(a.fi * b.fi % p1, a.se * b.se % p2); }
  29. pll operator+(const pll& a, const ll& b) { return pll((a.fi + b) % p1, (a.se + b) % p2); }
  30. pll operator-(const pll& a, const pll& b) { return pll((a.fi - b.fi + p1) % p1, (a.se - b.se + p2) % p2); }
  31. pll operator+(const pll& a, const pll& b) { return pll((a.fi + b.fi) % p1, (a.se + b.se) % p2); }
  32. pll pw[N];
  33. void init(int n) {
  34. pw[0] = { 1, 1 };
  35. for (int i = 1; i <= n; ++i) pw[i] = pw[i - 1] * bs;
  36. }
  37. struct dat {
  38. pll f; int len;
  39. dat() { f = { 0,0 };len = 0; }
  40. dat(const pll& _f, const int& _len) { f = _f; len = _len; }
  41. };
  42. dat operator*(const dat& a, const dat& b) {
  43. return dat(a.f * pw[b.len] + b.f, a.len + b.len);
  44. }
  45. ostream& operator<<(ostream& out, const dat& a) {
  46. return out << "dat{ (" << a.f.first << ", " << a.f.second << "), l=" << a.len << " } ";
  47. }
  48. }using namespace seq_Hash;
  49. namespace segt {
  50. #define ls(p) t[p].l
  51. #define rs(p) t[p].r
  52. #define mid ((l+r)>>1)
  53. struct node {
  54. int l, r; dat d;
  55. }t[N * 30];
  56. int sz, root;
  57. int newnode() { ++sz;t[sz] = { 0,0,dat() }; return sz; }
  58. void pushup(int p) { t[p].d = t[ls(p)].d * t[rs(p)].d; }
  59. void modify(int p, int& q, int ps, int l = 1, int r = n) {
  60. if (!q) q = newnode();
  61. if (l == r) { t[q].d.f = t[p].d.f + 1;t[q].d.len = 1;return; }
  62. if (ps <= mid) modify(ls(p), ls(q), ps, l, mid), rs(q) = rs(p);
  63. else modify(rs(p), rs(q), ps, mid + 1, r), ls(q) = ls(p);
  64. pushup(q);
  65. assert(t[p].d.len == r - l + 1);
  66. assert(t[q].d.len == r - l + 1);
  67. }
  68. void build(int& p, int l = 1, int r = n) {
  69. p = newnode();
  70. if (l == r) { t[p].d.len = 1;t[p].d.f = pll(0, 0);return; }
  71. build(ls(p), l, mid); build(rs(p), mid + 1, r);
  72. pushup(p);
  73. assert(t[p].d.len == r - l + 1);
  74. }
  75. void print(int p, int l = 1, int r = n) {
  76. if (l == r) {
  77. assert(t[p].d.f.first == t[p].d.f.second);
  78. for (int i = 0;i < t[p].d.f.first;++i) printf("%d ", P[l]);
  79. return;
  80. }
  81. print(ls(p), l, mid); print(rs(p), mid + 1, r);
  82. }
  83. int cmp(int p, int q, int ps = n + 1, int l = 1, int r = n, bool fg = 0) {
  84. if (q == 0) return -1;
  85. if (l == r) {
  86. ll v = t[p].d.f.fi + (ll)(ps == l) - t[q].d.f.fi;
  87. if (v == 0) return 0;
  88. return (v < 0) ? -1 : 1;
  89. }
  90. pll _p = t[ls(p)].d.f + ((l <= ps && ps <= mid) ? (pw[mid - ps]) : (pll{ 0,0 }));
  91. pll _q = t[ls(q)].d.f;
  92. if (_p == _q) return cmp(rs(p), rs(q), ps, mid + 1, r, fg);
  93. return cmp(ls(p), ls(q), ps, l, mid, fg);
  94. }
  95. }
  96. struct pp { int u, id; };
  97. bool operator<(const pp a, const pp b) {
  98. int t = segt::cmp(a.id, b.id);
  99. return (t == 0) ? (a.id < b.id) : (t < 0);
  100. }
  101. bool operator>(const pp a, const pp b) { return b < a; }
  102. pp dis[N];
  103. bool vis[N]; int pre[N];
  104. void dij() {
  105. set<pp> Q;
  106. segt::build(segt::root);
  107. dis[1] = pp{ 1,0 };
  108. segt::modify(segt::root, dis[1].id, w[1]);
  109. Q.insert(dis[1]);
  110. while (!Q.empty()) {
  111. int u = Q.begin()->u;Q.erase(Q.begin());
  112. if (vis[u]) continue;
  113. vis[u] = 1;
  114. if (u == n) break;
  115. for (int i = head[u];i;i = nxt[i]) {
  116. int v = pnt[i]; if (vis[v]) continue;
  117. if (segt::cmp(dis[u].id, dis[v].id, w[v]) < 0) {
  118. auto it = Q.find(dis[v]);
  119. if (it != Q.end()) Q.erase(it);
  120. dis[v].u = v;dis[v].id = 0;
  121. segt::modify(dis[u].id, dis[v].id, w[v]);
  122. Q.insert(dis[v]);
  123. pre[v] = u;
  124. }
  125. }
  126. }
  127. }
  128. int main() {
  129. read(n, m); init(n);
  130. for (int i = 1;i <= n;++i) read(P[i]), PP[P[i]] = i;
  131. for (int i = 1;i <= n;++i) read(w[i]), w[i] = PP[w[i]];
  132. for (int i = 1;i <= m;++i) {
  133. int u, v;read(u, v);
  134. adde(u, v);adde(v, u);
  135. }
  136. dij();
  137. segt::print(dis[n].id);
  138. puts("");
  139. return 0;
  140. }

XJOI4588

备用链接1 备用链接2

  1. #pragma GCC optimize(2)
  2. #pragma GCC optimize(3)
  3. #include <bits/stdc++.h>
  4. #define fi first
  5. #define se second
  6. using namespace std;
  7. typedef long long ll;
  8. typedef unsigned long long ull;
  9. typedef pair<ll, ll> pll;
  10. const int N = 1000010;
  11. const int mod = 998244353;
  12. const int p1 = 1e9 + 7;
  13. const int p2 = 1e9 + 9;
  14. const int base = 433;
  15. template<size_t SIZE>
  16. struct hashmap {
  17. static const int MOD = (1 << 21);
  18. int head[MOD], nxt[SIZE], st[SIZE], top, E;
  19. ull key[SIZE];
  20. inline int find(ull _key) {
  21. int hah = _key & (MOD - 1);
  22. for (int i = head[hah];i;i = nxt[i]) {
  23. if (_key == key[i]) return i;
  24. }
  25. return -1;
  26. }
  27. inline int insert(ull _key) {
  28. int hah = _key & (MOD - 1);
  29. if (head[hah] == 0) st[++top] = hah;
  30. E++;key[E] = _key;nxt[E] = head[hah];head[hah] = E;
  31. return E;
  32. }
  33. inline void clear() {
  34. while (top) head[st[top--]] = 0;E = 0;
  35. }
  36. };
  37. hashmap<N * 2> vs, mp;
  38. ll fpow(ll a, ll b) { ll r = 1;for (;b;b >>= 1, a = (a * a) % mod) r = (r * a) % mod;return r; }
  39. ll inv[N], fac[N];ull pww[N << 1];
  40. pll pw[N], hah[N];
  41. char s[N];int n;
  42. pll operator*(const pll a, const ll b) { return pll(a.fi * b % p1, a.se * b % p2); }
  43. pll operator*(const pll a, const pll b) { return pll(a.fi * b.fi % p1, a.se * b.se % p2); }
  44. pll operator+(const pll a, const ll b) { return pll((a.fi + b) % p1, (a.se + b) % p2); }
  45. pll operator-(const pll a, const pll b) { return pll((a.fi - b.fi + p1) % p1, (a.se - b.se + p2) % p2); }
  46. void print(pll a) { printf("(%lld,%lld)\n", a.fi, a.se); }
  47. pll gethash(int l, int r) { return hah[r] - (hah[l - 1] * pw[r - l + 1]); }
  48. void init() {
  49. pw[0] = pll(1ll, 1ll);
  50. for (int i = 1;i <= n;i++) {
  51. pw[i] = pw[i - 1] * (ll)base;
  52. hah[i] = hah[i - 1] * (ll)base + (ll)(s[i] - 'a' + 1);
  53. }
  54. fac[0] = fac[1] = inv[0] = inv[1] = 1;
  55. for (int i = 2;i <= n;i++) {
  56. fac[i] = fac[i - 1] * i % mod;
  57. inv[i] = (mod - mod / i) * inv[mod % i] % mod;
  58. }
  59. pww[0] = { 1ull };
  60. for (int i = 1;i <= 2 * n;i++) pww[i] = pww[i - 1] * 557ull;
  61. }
  62. ull tomask(pll a) {
  63. ull x = (ull)a.fi << 32 | (ull)a.se;
  64. x ^= x << 14;x ^= x >> 16;x ^= x << 7;
  65. return x ^ 1919810;
  66. }
  67. int cnt[N << 1], id[N << 1];
  68. int main() {
  69. scanf("%s", s + 1);
  70. n = strlen(s + 1);
  71. init();
  72. ll ress = 0;
  73. for (int d = 1;d <= n;d++) {
  74. int t = n / d, rs = n % d;
  75. vs.clear();mp.clear();
  76. ll ans = fac[t], res = 0;ull mask = 0;
  77. for (int i = 1;i <= t;i++) {
  78. // (i-1)*d+1 ~ i*d
  79. ull tmp = tomask(gethash((i - 1) * d + 1, i * d));
  80. int p = mp.find(tmp);
  81. if (p == -1) {
  82. cnt[p = mp.insert(tmp)] = 1;
  83. }
  84. else {
  85. cnt[p]++;ans = (ans * inv[cnt[p]]) % mod;
  86. }
  87. id[i * 2 - 1] = p; mask += pww[p];
  88. tmp = tomask(gethash((i - 1) * d + 1 + rs, i * d + rs));
  89. p = mp.find(tmp);
  90. if (p == -1) { p = mp.insert(tmp);cnt[p] = 0; }
  91. id[i * 2] = p;
  92. }
  93. res = (res + ans) % mod;
  94. vs.insert(mask);
  95. if (rs) {
  96. for (int i = t;i >= 1;i--) {
  97. ans = (ans * cnt[id[i * 2 - 1]]) % mod;
  98. cnt[id[i * 2 - 1]]--;
  99. mask -= pww[id[i * 2 - 1]];
  100. ans = (ans * inv[++cnt[id[i * 2]]]) % mod;
  101. mask += pww[id[i * 2]];
  102. if (vs.find(mask) != -1) continue;
  103. vs.insert(mask);
  104. res = (res + ans) % mod;
  105. }
  106. }
  107. ress = (ress + res) % mod;
  108. }
  109. printf("%lld\n", ress);
  110. return 0;
  111. }

UOJ522

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define LL long long
  4. #define pii pair<int, int>
  5. const int maxN = 1005, mod = 1472172389;
  6. mt19937 rnd( time(NULL) );
  7. int h[maxN + 1][26];
  8. char ans[maxN + 1];
  9. inline void update(int &x, int y) { x = (LL)x + y >= mod ? (LL)x + y - mod : (LL)x + y; }
  10. struct Graph
  11. {
  12. int n, m, cnt;
  13. int res[maxN + 1], tp[maxN + 1];
  14. int f[maxN + 1][maxN + 1];
  15. vector<pii> to[maxN + 1];
  16. void init()
  17. {
  18. scanf("%d %d", &n, &m);
  19. for(int i = 1; i <= m; i++)
  20. {
  21. int x, y;
  22. char c[2];
  23. scanf("%d %d %s", &x, &y, c);
  24. to[x].push_back( pii(y, c[0] - 'a') );
  25. }
  26. for(int i = 1; i <= n; i++) f[0][i] = res[i] = 1;
  27. }
  28. int calc()
  29. {
  30. cnt ++;
  31. int sum = 0;
  32. for(int u = 1; u <= n; u++)
  33. {
  34. int res = 0;
  35. for(int i = 0; i < to[u].size(); i++)
  36. {
  37. int v = to[u][i].first, c = to[u][i].second;
  38. update(res, 1ll * h[cnt][c] * f[cnt - 1][v] % mod);
  39. }
  40. update(sum, f[cnt][u] = res);
  41. }
  42. return sum;
  43. }
  44. int get(int nc)
  45. {
  46. for(int i = 1; i <= n; i++) tp[i] = 0;
  47. int sum = 0;
  48. for(int u = 1; u <= n; u++)
  49. for(int i = 0; i < to[u].size(); i++)
  50. {
  51. int v = to[u][i].first, c = to[u][i].second;
  52. if(c != nc) continue;
  53. int t = 1ll * res[u] * h[cnt][c] % mod;
  54. update(tp[v], t);
  55. update(sum, 1ll * t * f[cnt - 1][v] % mod);
  56. }
  57. return sum;
  58. }
  59. void upd()
  60. {
  61. for(int i = 1; i <= n; i++) res[i] = tp[i];
  62. cnt --;
  63. }
  64. }G1, G2;
  65. int main()
  66. {
  67. for(int i = 1; i <= 1001; i++)
  68. for(int c = 0; c < 26; c++)
  69. h[i][c] = rnd() % (mod - 1) + 1;
  70. G1.init(); G2.init();
  71. for(int i = 1; i <= 1001; i++)
  72. if(G1.calc() != G2.calc())
  73. {
  74. for(int j = 1; j <= i; j++)
  75. for(int c = 0; c < 26; c++)
  76. if(G1.get(c) != G2.get(c))
  77. {
  78. ans[j] = c + 'a';
  79. G1.upd(); G2.upd();
  80. break;
  81. }
  82. printf("%s\n", ans + 1);
  83. return 0;
  84. }
  85. puts("Same");
  86. return 0;
  87. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注