zoukankan      html  css  js  c++  java
  • luoguP4389 付公主的背包 多项式exp


    %%%dkw

    话说这是个论文题来着...

    考虑生成函数(OGF)

    对于价值为(v)的物品,由于有(10^5)的件数,可以看做无限个

    那么,其生成函数为(x^0 + x^{v} + x^{2v} + ... = frac{1}{1 - x^v})

    我们所需的答案即([x^n] prod frac{1}{1 - x^{v_i}})

    只需考虑求出(A = prod frac{1}{1 - x^{v_i}})

    自然地想到取对数

    (In(A) = sum In(frac{1}{1 - x^{v_i}}))


    不难发现

    (In(frac{1}{1 - x^v}) = - In(1 - x^v))

    考虑用麦克劳林级数来模拟,那么

    由于(In^{(n)}(1 - x) = - frac{1}{(1 - x)^n} * (n - 1)!)

    (-In(1 - x^v) = sum frac{x^{vi}}{i})

    于是,我们可以直接枚举倍数,在(O(m log m))的时间内完成计算

    最后只要(O(m log m))(exp)一下即可


    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define ri register int
    #define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
    #define drep(io, ed, st) for(ri io = ed; io >= st; io --)
    
    #define gc getchar
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    
    const int sid = 500050;
    const int mod = 998244353;
    
    int n, m;
    int V[sid], F[sid], inv[sid], rev[sid], ans[sid];
    
    inline int Inc(int a, int b) { return (a + b >= mod) ? a + b - mod : a + b; }
    inline int Dec(int a, int b) { return (a - b < 0) ? a - b + mod : a - b; }
    inline int mul(int a, int b) { return 1ll * a * b % mod; }
    inline int fp(int a, int k) {
    	int ret = 1;
    	for( ; k; k >>= 1, a = mul(a, a))
    		if(k & 1) ret = mul(ret, a);
    	return ret;
    }
    	
    inline void init(int Maxn, int &n, int &lg) {
    	n = 1; lg = 0;
    	while(n < Maxn) n <<= 1, lg ++;
    }
    	
    inline void NTT(int *a, int n, int opt) {
    	for(ri i = 0; i < n; i ++) if(i < rev[i]) swap(a[i], a[rev[i]]);
    	for(ri i = 1; i < n; i <<= 1)
    	for(ri j = 0, g = fp(3, (mod - 1) / (i << 1)); j < n; j += (i << 1))
    	for(ri k = j, G = 1; k < i + j; k ++, G = mul(G, g)) {
    		int x = a[k], y = mul(G, a[i + k]);
    		a[k] = (x + y >= mod) ? x + y - mod : x + y;
    		a[i + k] = (x - y < 0) ? x - y + mod : x - y;
    	}
    	if(opt == -1) {
    		int ivn = fp(n, mod - 2);
    		reverse(a + 1, a + n);
    		rep(i, 0, n) a[i] = mul(a[i], ivn);
    	}
    }
    
    int ia[sid], ib[sid];
    inline void Inv(int *a, int *b, int n) {
    	if(n == 1) { b[0] = fp(a[0], mod - 2); return; }
    	Inv(a, b, n >> 1);
    	
    	int N = 1, lg = 0; init(n + n, N, lg);
    	for(ri i = 0; i < N; i ++)
    		rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
    	
    	for(ri i = 0; i < N; i ++) ia[i] = ib[i] = 0;
    	for(ri i = 0; i < n; i ++) ia[i] = a[i], ib[i] = b[i];
    	
    	NTT(ia, N, 1); NTT(ib, N, 1);
    	for(ri i = 0; i < N; i ++)
    		ia[i] = Dec((ib[i] << 1) % mod, mul(ia[i], mul(ib[i], ib[i])));
    	NTT(ia, N, -1);
    	
    	for(ri i = 0; i < n; i ++) b[i] = ia[i];
    }
    
    inline void Inv_init(int n) {
    	inv[0] = inv[1] = 1;
    	rep(i, 2, n) inv[i] = mul(inv[mod % i], mod - mod / i);
    }
    
    inline void wf(int *a, int *b, int n) { for(ri i = 1; i < n; i ++) b[i - 1] = mul(a[i], i); }
    inline void jf(int *a, int *b, int n) { for(ri i = 1; i < n; i ++) b[i] = mul(a[i - 1], inv[i]); }
    	
    int iv[sid], dx[sid];
    inline void In(int *a, int *b, int n) {
    	for(ri i = 0; i < n + n; i ++) iv[i] = dx[i] = 0;
    	Inv(a, iv, n); wf(a, dx, n);
    	
    	int N = 1, lg = 0; init(n + n, N, lg);
    	for(ri i = 0; i < N; i ++)
    		rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
    	
    	NTT(iv, N, 1); NTT(dx, N, 1);
    	for(ri i = 0; i < N; i ++) iv[i] = mul(iv[i], dx[i]);
    	NTT(iv, N, -1); jf(iv, b, n);
    }
    
    
    int inb[sid], fb[sid];
    inline void Exp(int *a, int *b, int n) {
    	if(n == 1) { b[0] = 1; return; }
    	Exp(a, b, n >> 1); 
    	
    	
    	for(ri i = 0; i < n + n; i ++) inb[i] = fb[i] = 0;
    	In(b, inb, n);
    	
    	int N = 1, lg = 0; init(n + n, N, lg);
    	for(ri i = 0; i < N; i ++) 
    		rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
    	
    	for(ri i = 0; i < n; i ++) fb[i] = Dec(a[i], inb[i]); fb[0] ++;
    	for(ri i = 0; i < n; i ++) inb[i] = b[i];
    	
    	NTT(inb, N, 1); NTT(fb, N, 1);
    	for(ri i = 0; i < N; i ++) fb[i] = mul(fb[i], inb[i]);
    	NTT(fb, N, -1);
    	
    	for(ri i = 0; i < n; i ++) b[i] = fb[i], b[i + n] = 0;
    }
    	
    inline void calc() {
    	int N = 1, lg = 0;
    	init(m + 5, N, lg); Inv_init(N);
    	for(ri i = 1; i <= m; i ++)
    		for(ri j = i; j <= m; j += i)
    			F[j] = Inc(F[j], mul(V[i], inv[j / i]));
    	Exp(F, ans, N);
    	rep(i, 1, m) printf("%d
    ", ans[i]);
    }
    	
    int main() {
    	n = read(); m = read();
    	rep(i, 1, n) V[read()] ++;
    	calc();
    	return 0;
    }
    
  • 相关阅读:
    WebRTC相关技术预研总结
    What is "jar.mn"?
    (FFOS Gecko & Gaia) OTA
    (FFOS Gecko & Gaia) OTA
    (FFOS Gecko & Gaia) OTA
    (FFOS Gecko & Gaia) OTA
    (FFOS Gecko & Gaia) OTA
    (FFOS Gecko & Gaia) OTA
    (FFOS Gecko & Gaia) OTA
    EF实体框架 5 性能注意事项
  • 原文地址:https://www.cnblogs.com/reverymoon/p/10181717.html
Copyright © 2011-2022 走看看