• hdu 6589


    NTT

    首先发现操作的交换不影响答案

    然后再打表,发现每项是一个组合数

    然后NTT处理就行了

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e6 + 5, P = 998244353;
    namespace NTT {
        int power(int x, int t) {
            int ret = 1;
            for(; t; t >>= 1, x = 1LL * x * x % P) 
                if(t & 1)
                    ret = 1LL * ret * x % P;
            return ret;
        }
        void NTT(int *a, int len, int f) {     
            int n = 1 << len;
            for(int i = 0; i < n; ++i) {
                int t = 0;
                for(int j = 0; j < len; ++j) 
                    if(i >> j & 1) 
                        t |= 1 << (len - j - 1); 
                if(i < t) swap(a[i], a[t]);
            }
            for(int l = 2; l <= n; l <<= 1) {
                int m = l >> 1;
                int w = power(3, f == 1 ? (P - 1) / l : (P - 1) - (P - 1) / l);
                for(int i = 0; i < n; i += l) {
                    int t = 1;
                    for(int k = 0; k < m; ++k, t = 1LL * t * w % P) {
                        int x = a[i + k], y = 1LL * t * a[i + m + k] % P;
                        a[i + k] = (x + y) % P;
                        a[i + k + m] = ((x - y) % P + P) % P;
                    }
                }       
            }
            if(f == -1) {
                int inv = power(n, P - 2);
                for(int i = 0; i < n; ++i) a[i] = 1LL * a[i] * inv % P;
            }
        }
        void mul(int *a, int *b, int *c, int len) {
            static int tmp[maxn];
            NTT(a, len, 1);
            NTT(b, len, 1);
            int n = 1 << len;
            for(int i = 0; i < n; ++i) tmp[i] = 1LL * a[i] * b[i] % P;
            NTT(a, len, -1);
            NTT(b, len, -1);
            NTT(tmp, len, -1);
            for(int i = 0; i < n; ++i) c[i] = tmp[i];
        }
        void mul(int *a, int *b, int len) {
            NTT(a, len, 1);
            NTT(b, len, 1);
            int n = 1 << len;
            for(int i = 0; i < n; ++i) a[i] = 1LL * a[i] * b[i] % P;
            NTT(a, len, -1);
        }
    } using namespace NTT;
    int n, m;
    int a[maxn], cnt[5], fac[maxn], facinv[maxn], inv[maxn], b[maxn];
    int C(int n, int m) {
        if(n < m) return 0;
        return 1LL * fac[n] * facinv[m] % P * facinv[n - m] % P;
    }
    int main() {
        fac[0] = 1;
        inv[1] = 1;
        facinv[0] = 1;
        for(int i = 1; i < maxn; ++i) {
            fac[i] = 1LL * fac[i - 1] * i % P;
            if(i != 1) inv[i] = 1LL * (P - P / i) * inv[P % i] % P;
            facinv[i] = 1LL * facinv[i - 1] * inv[i] % P;
        }
        int T; scanf("%d", &T);
        while(T--) {
            memset(cnt, 0, sizeof(cnt));
            scanf("%d%d", &n, &m);
            for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
            while(m--) {
                int x; scanf("%d", &x);
                ++cnt[x];
            }
            int t = 0;
            while(1 << t <= 2 * n) ++t;
            int m = 1 << t;
            for(int j = 1; j <= 3; ++j) if(cnt[j]) {
                for(int i = 0; i * j < n; ++i) b[i * j] = C(cnt[j] + i - 1, i);
                mul(a, b, t);
                for(int i = 0; i < m; ++i) b[i] = 0;
                for(int i = n; i < m; ++i) a[i] = 0;
            }
            ll ans = 0;
            for(int i = 0; i < n; ++i) ans ^= 1LL * (i + 1) * a[i];
            printf("%lld
    ", ans); 
        }
        return 0;
    }
    View Code
  • 相关阅读:
    js正则表达语法
    Codeforces 976E/925C (01Trie树)
    ZOJ 3879(大模拟)
    CF967C(二分+细节)
    CF967A(细节模拟)
    HDU 2222(AC自动机模板)
    HDU 5510(KMP+思维)
    HDU 6273(树状数组+思维)
    HDU 6266(思维+规律)
    HDU 6264(思维)
  • 原文地址:https://www.cnblogs.com/19992147orz/p/11561304.html
Copyright © 2020-2023  润新知