Loading

P2336 [SCOI2012] 喵星球上的点名

考虑哈希,由于不同长度的串只有 \(\sqrt{\sum len}\) 种,直接做就没了,具体见代码。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
// typedef __int128 i128;
typedef pair<int, int> pii;
const int N = 2e5 + 10, bas = 19260817, mod = 998244353;
template<typename T>
void dbg(const T &t) { cout << t << endl; }
template<typename Type, typename... Types>
void dbg(const Type& arg, const Types&... args) {
    cout << arg << ' ';
    dbg(args...);
}
namespace Loop1st {
int n, m, ans[N];
ull h[N], pw[N], f[N];
unordered_map<ull, int>mp, cnt, vis;
vector<int>buc;
basic_string<int>s[N];
ull geth(int l, int r) {
    if (!l) return h[r];
    return h[r] - h[l - 1] * pw[r - l + 1];
}
void main() {
    pw[0] = 1;
    for (int i = 1; i < N; i++) pw[i] = pw[i - 1] * bas;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        int x, y;
        cin >> x; while (x--) cin >> y, s[i] += y + 1;
        s[i] += 1 << 30;
        cin >> x; while (x--) cin >> y, s[i] += y + 1;
    }
    for (int i = 1; i <= m; i++) {
        int x, y;
        ull hsh = 0;
        cin >> x; buc.push_back(x); while (x--) cin >> y, hsh = hsh * bas + y + 1;
        f[i] = hsh; cnt[hsh]++;
    }
    sort(buc.begin(), buc.end()); buc.erase(unique(buc.begin(), buc.end()), buc.end());
    for (int i = 1; i <= n; i++) {
        vis.clear();
        h[0] = s[i][0];
        int sz = (int)s[i].size();
        for (int j = 1; j < sz; j++) h[j] = h[j - 1] * bas + s[i][j];
        for (int len : buc) {
            for (int j = len - 1; j < sz; j++) {
                ull tmp = geth(j - len + 1, j);
                if (cnt.count(tmp) && !vis.count(tmp)) vis[tmp] = 1, ans[i] += cnt[tmp];
            }
        }
        for (auto [tmp, _] : vis) mp[tmp]++;
    }
    for (int i = 1; i <= m; i++) cout << mp[f[i]] << '\n';
    for (int i = 1; i <= n; i++) cout << ans[i] << " \n"[i == n];
}

}
int main() {
    // freopen("data.in", "r", stdin);
    // freopen("data.out", "w", stdout);
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int T = 1;
    // cin >> T;
    while (T--) Loop1st::main();
    return 0;
}
// start coding at 14:18
// finish debugging at 14:42
posted @ 2026-01-07 14:49  循环一号  阅读(6)  评论(0)    收藏  举报