RE求解
  • 板块P9149 串串题
  • 楼主dread
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/3/15 17:29
  • 上次更新2023/10/23 21:29:29
查看原帖
RE求解
197658
dread楼主2023/3/15 17:29
#include <bits/stdc++.h>

const int N = 1e6 + 4, mod = 1e9 + 7;
int n, m, w, d;
int a[N], b[N], nxt[N];
std::pair < int , int > c[N];
int tot;

inline int add(int a, int b) { return (a += b) >= mod ? a - mod : a; }
inline int sub(int a, int b) { return (a -= b) < 0 ? a + mod : a; }
inline int mul(int a, int b) { return 1LL * a * b % mod; }
inline void Add(int &a, int b) { a = add(a, b); }
inline void Sub(int &a, int b) { a = sub(a, b); }
inline void Mul(int &a, int b) { a = mul(a, b); }
inline int quickpow(int a, int b) {
    int re = 1;
    while(b) {
        if(b & 1) Mul(re, a);
        b >>= 1;
        Mul(a, a);
    }
    return re;
}

int Map[N];

int fac[N], inv[N];
inline int input(int n) {
    fac[0] = 1;
    for(int i = 1; i <= n; ++i) fac[i] = mul(fac[i - 1], i);
    inv[n] = quickpow(fac[n], mod - 2);
    for(int i = n; i >= 1; --i) inv[i - 1] = mul(inv[i], i);
}

inline int C(int n, int m) {
    if(n < m || n < 0 || m < 0) return 0;
    return mul(fac[n], mul(inv[m], inv[n - m]));
}


int Mp[N], Size;
inline void solve() {
    std::cin >> n >> m >> w >> d;
    for(int i = 1; i <= n; ++i) std::cin >> a[i];
    memset(Mp, 0, sizeof(Mp));
    Size = 0;
    for(int i = 1; i <= m; ++i) {
        std::cin >> b[i];
        ++Mp[b[i]];
        if(Mp[b[i]] == 1) ++Size;
    }
    if(Size + d > w) {
        std::cout << "0\n";
        return ;
    }
    tot = 0;
    for(int i = 1; i <= n; ++i) if(Mp[a[i]]) c[++tot] = std::make_pair(a[i], i);
    if(tot < m) {
        std::cout << "0\n";
        return ;
    }
    w -= Size;
    memset(nxt, 0, sizeof(nxt));
    for(int i = 2, j = 0; i <= m; ++i) {
        while(j && b[i] != b[j + 1]) j = nxt[j];
        if(b[j + 1] == b[i]) ++j;
        nxt[i] = j;
    }
    memset(Map, 0, sizeof(Map));
    int ans = 0;
    int l = 1, r = 0;
    int pos = 0;
    for(int i = 1, j = 0; i <= tot; ++i) {
        while(j > 0 && b[j + 1] != c[i].first) j = nxt[j];
        if(b[j + 1] == c[i].first) ++j;
        if(j == m) {
            int L = c[i - j + 1].second, R = c[i].second;
            while(r < R) {
                ++r;
                if(!Mp[a[r]]) {
                    Map[a[r]]++;
                    if(Map[a[r]] == 1) ++pos;
                }
            }
            while(l < L) {
                if(!Mp[a[l]]) {
                    Map[a[l]]--;
                    if(Map[a[l]] == 0) --pos;
                }
                ++l;
            }
            Add(ans, C(w - pos, d - pos));
            // std::cout << w - pos << ' ' << d - pos << '\n';
            j = nxt[j];
        }
    }
    std::cout << ans << '\n';
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    input(1e6);
    int T;
    std::cin >> T;
    while(T--) solve();
    return 0;
}
2023/3/15 17:29
加载中...