P5112 FZOUTSY

// by Isaunoya
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize( 
    "inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2,-ffast-math,-fsched-spec,unroll-loops,-falign-jumps,-falign-loops,-falign-labels,-fdevirtualize,-fcaller-saves,-fcrossjumping,-fthread-jumps,-funroll-loops,-freorder-blocks,-fschedule-insns,inline-functions,-ftree-tail-merge,-fschedule-insns2,-fstrict-aliasing,-fstrict-overflow,-falign-functions,-fcse-follow-jumps,-fsched-interblock,-fpartial-inlining,no-stack-protector,-freorder-functions,-findirect-inlining,-fhoist-adjacent-loads,-frerun-cse-after-loop,inline-small-functions,-finline-small-functions,-ftree-switch-conversion,-foptimize-sibling-calls,-fexpensive-optimizations,inline-functions-called-once,-fdelete-null-pointer-checks")
#include <bits/stdc++.h>
#include <unordered_map>

using namespace std;
using ll = long long;
// using ull = unsigned long long;
int n, m, k;
#define ull ll
const int maxn = 3e6 + 63;
int a[maxn];
ull hsh[maxn], bs[maxn], qwq[maxn];
const int base = 233;
unordered_map<ull, int> mp;

int read() {
  int x = 0;
  char c = getchar();
  while (c < 48) c = getchar();
  while (c > 47) x = x * 10 + (c - 48), c = getchar();
  return x;
}

char getc() {
  char c = getchar();
  while (c > 'z' || c < 'a') c = getchar();
  return c;
}

int t[maxn], cnt[maxn], bl[maxn];
long long ans[maxn];
struct que {
  int l, r, id;
  bool operator<(const que& other) const {
    if (bl[l] == bl[other.l]) return l < other.l;
    return r < other.r;
  }
};
que q[maxn];

int main() {
  n = read(), m = read(), k = read();
  for (int i = 1; i <= n; i++) {
    char c = getc();
    a[i] = c - 'a';
  }
  bs[0] = 1;
  for (int i = 1; i <= n; i++) bs[i] = bs[i - 1] * base;
  for (int i = n; i; i--) qwq[i] = qwq[i + 1] * base + a[i];
  int id = 0;
  for (int i = 1; i <= n - k + 1; i++) {
    ull res = qwq[i] - qwq[i + k] * bs[k];
    if (!mp.count(res)) mp[res] = ++id;
    t[i] = mp[res];
  }
  int block = n / sqrt(m);
  for (int i = 1; i <= n; i++) bl[i] = i / block;
  for (int i = 1; i <= m; i++) {
    int l = read(), r = read();
    if (r > n - k + 1) r = n - k + 1;
    if (l > r) l = 1, r = 0;
    q[i] = { l, r, i };
  }
  sort(q + 1, q + m + 1);
  int l = 1, r = 0;
  ll now = 0;
  for (int i = 1; i <= m; i++) {
    while (l > q[i].l) now += cnt[t[--l]]++;
    while (r < q[i].r) now += cnt[t[++r]]++;
    while (l < q[i].l) now -= --cnt[t[l++]];
    while (r > q[i].r) now -= --cnt[t[r--]];
    ans[q[i].id] = now;
  }
  for (int i = 1; i <= m; i++) printf("%lld
", ans[i]);
  return 0;
}
原文地址:https://www.cnblogs.com/Isaunoya/p/12346558.html