• [SDOI2017]遗忘的集合


    题面

    题解

    (a_i = 0/1)表示元素(i)是否在集合(S)中。

    那么(f)的生成函数为(displaystyle F(x) = prod_{i=1}^infty left(frac 1{1 - x ^ i} ight) ^ {a_i}),于是问题就变成了我们已知(F),求(a)

    两边同时取负对数,得到(displaystyle -ln F(x) = sum_{i=1}^infty a_i ln (1 - x ^ i)),对(ln (1 - x ^ i))进行泰勒展开,有

    (displaystyle -ln F(x) = sum_{i = 1} ^ infty a_i sum_{j=1} ^ infty -frac{x ^ {ij}} j),将(ij)换元为(T),有(displaystyle ln F(x) = sum_{T=1}^infty x ^ T sum_{i | T} a_i imes frac iT)

    我们对(F(x))求一个(ln),那么(frac 1Tsum_{i|T} a_i imes i = [x ^ T](ln F(x))),莫比乌斯反演一下(a_i)就出来了。

    代码

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
    
    inline int read()
    {
    	int data = 0, w = 1; char ch = getchar();
    	while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    	if (ch == '-') w = -1, ch = getchar();
    	while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int maxn(6e5 + 10);
    const double pi(acos(-1));
    struct complex { double x, y; } w[maxn];
    inline complex conj(const complex &x) { return (complex) {x.x, -x.y}; }
    inline complex operator + (const complex &lhs, const complex &rhs)
    	{ return (complex) {lhs.x + rhs.x, lhs.y + rhs.y}; }
    inline complex operator - (const complex &lhs, const complex &rhs)
    	{ return (complex) {lhs.x - rhs.x, lhs.y - rhs.y}; }
    inline complex operator * (const complex &lhs, const complex &rhs)
    {
    	return (complex) {lhs.x * rhs.x - lhs.y * rhs.y,
    		lhs.x * rhs.y + lhs.y * rhs.x};
    }
    
    int r[maxn], Mod;
    int fastpow(int x, int y)
    {
    	int ans = 1;
    	for (; y; y >>= 1, x = 1ll * x * x % Mod)
    		if (y & 1) ans = 1ll * ans * x % Mod;
    	return ans;
    }
    
    void FFT(complex *p, int N)
    {
    	for (int i = 0; i < N; i++) if (i < r[i]) std::swap(p[i], p[r[i]]);
    	for (int i = 1, s = 2, t = N; i < N; i <<= 1, s <<= 1, t >>= 1)
    		for (int j = 0; j < N; j += s) for (int k = 0, o = 0; k < i; ++k, o += t)
    		{
    			complex x = p[j + k], y = w[o] * p[i + j + k];
    			p[j + k] = x + y, p[i + j + k] = x - y;
    		}
    }
    
    void MTT(int N, int *lhs, int *rhs, int *ans)
    {
    	int i; static complex a[maxn], b[maxn]; typedef long long Long;
    	static complex A[maxn], B[maxn], C[maxn], D[maxn];
    	for (i = 0; i < N; i++) a[i].x = lhs[i] & 0x7fff, a[i].y = lhs[i] >> 15;
    	for (i = 0; i < N; i++) b[i].x = rhs[i] & 0x7fff, b[i].y = rhs[i] >> 15;
    	FFT(a, N), FFT(b, N);
    	for (i = 0; i < N; i++)
    	{
    		int j = (N - i) & (N - 1);
    		static complex da, db, dc, dd;
    		da = (a[i] + conj(a[j])) * (complex) {.5, 0.};
    		db = (a[i] - conj(a[j])) * (complex) {0, -.5};
    		dc = (b[i] + conj(b[j])) * (complex) {.5, 0.};
    		dd = (b[i] - conj(b[j])) * (complex) {0, -.5};
    		A[j] = da * dc, B[j] = da * dd, C[j] = db * dc, D[j] = db * dd;
    	}
    	for (i = 0; i < N; i++) a[i] = A[i] + B[i] * (complex) {0, 1};
    	for (i = 0; i < N; i++) b[i] = C[i] + D[i] * (complex) {0, 1};
    	FFT(a, N), FFT(b, N);
    	for (i = 0; i < N; i++)
    	{
    		int da = (Long) (a[i].x / N + .5) % Mod,
    			db = (Long) (a[i].y / N + .5) % Mod,
    			dc = (Long) (b[i].x / N + .5) % Mod,
    			dd = (Long) (b[i].y / N + .5) % Mod;
    		ans[i] = (da + ((Long) (db + dc) << 15) % Mod + ((Long) dd << 30) % Mod) % Mod;
    	}
    }
    
    void Inv(int *a, int *b, int N)
    {
    	static int c[maxn];
    	if (N == 1) return (void) (*b = fastpow(*a, Mod - 2));
    	Inv(a, b, (N + 1) >> 1); int len = 1, P = -1;
    	while (len < (N << 1)) len <<= 1, ++P;
    	for (int i = 0; i < len; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << P);
    	for (int i = 0; i < len; i++) w[i] = (complex) {cos(pi * i / len), sin(pi * i / len)};
    	std::copy(a, a + N, c), std::fill(c + N, c + len, 0);
    	MTT(len, c, b, c);
    	std::fill(c + N, c + len, 0);
    	MTT(len, c, b, c);
    	for (int i = 0; i < N; i++) b[i] = (2ll * b[i] - c[i] + Mod) % Mod;
    }
    
    void Ln(int *f, int *g, int N)
    {
    	static int A[maxn], B[maxn];
    	for (int i = 1; i < N; i++) A[i - 1] = 1ll * i * f[i] % Mod;
    	A[N - 1] = 0, Inv(f, B, N); int P = -1, len = 1;
    	while (len < (N << 1)) len <<= 1, ++P;
    	for (int i = 0; i < len; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << P);
    	for (int i = 0; i < len; i++) w[i] = (complex) {cos(pi * i / len), sin(pi * i / len)};
    	MTT(len, A, B, A), g[0] = 0;
    	for (int i = 1; i < N; i++) g[i] = 1ll * A[i - 1] * fastpow(i, Mod - 2) % Mod;
    }
    
    int n, f[maxn], g[maxn], ans;
    int main()
    {
    	n = read(), Mod = read(), f[0] = 1;
    	for (int i = 1; i <= n; i++) f[i] = read();
    	Ln(f, g, n + 1);
    	for (int i = 1; i <= n; i++) g[i] = 1ll * g[i] * i % Mod;
    	for (int i = 1; i <= n; i++)
    		for (int j = i + i; j <= n; j += i)
    			g[j] = (g[j] - g[i] + Mod) % Mod;
    	for (int i = 1; i <= n; i++) if (g[i]) ++ans;
    	printf("%d
    ", ans);
    	for (int i = 1; i <= n; i++) if (g[i]) printf("%d ", i);
    	return 0;
    }
    
  • 相关阅读:
    Props文件属性读取
    Linux Centos6.5 SVN服务器搭建 以及客户端安装
    CF1081G Mergesort Strikes Back
    JAVA web 相关知识点
    mybatis学习10 事务控制
    某咨询公司面试
    四: git常用命令
    linux 学习2 常用命令
    mybatis学习九 缓存机制
    mybatis 学习八 mybatis如何控制事务的
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/10977520.html
Copyright © 2020-2023  润新知