zoukankan      html  css  js  c++  java
  • 城市规划

    题目传送门:城市规划

    题解

    如果无向连通图数量是 (F(x)) ,那么如果 (exp(F(x))=G(x)) 的话, (G(x)) 就是无向图数量。

    所以,直接使用 (F(x)=ln (G(x))) 。完了。

    总结:

    • 简单的多项式 (exp) 组合意义。

    代码

    可以得到如下代码(写个多项式 (ln) 就行了):

    #include <cstdio>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    const int N = (1 << 18) + 5, Mod = 1004535809, G = 3;
    int ad(int x, int y) { return ((x + y) > Mod) ? (x + y - Mod) : (x + y); }
    int dc(int x, int y) { return ((x - y) < 0) ? (x - y + Mod) : (x - y); }
    int ml(int x, int y) { return (ll) x * y % Mod; }
    int ksm(int x, ll y) {
    	int ret = 1;
    	for (; y; y >>= 1, x = ml(x, x))
    		if (y & 1) ret = ml(ret, x);
    	return ret;
    }
    int rev[N], g[25], ig[25];
    void Init() {
    	for (int i = 0; i <= 21; ++i) g[i] = ksm(G, (Mod - 1) >> i);
    	for (int i = 0; i <= 21; ++i) ig[i] = ksm(g[i], Mod - 2);
    }
    void GetRev(int up) {
    	for (int i = 0; i < up; ++i)
    		rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (up >> 1) : 0);
    }
    int GetUp(int deg) {
    	int ret = 1;
    	while (ret <= deg) ret <<= 1;
    	return ret;
    }
    void Clear(int *F, int L, int R) { //[L, R)
    	for (int i = L; i < R; ++i) F[i] = 0;
    }
    void Copy(int *G, const int *F, int L, int R) { //[L, R)
    	for (int i = L; i < R; ++i)
    		G[i] = F[i];
    }
    void NTT(int *F, int up, int ty) {
    	for (int i = 0; i < up; ++i)
    		if (i < rev[i]) swap(F[i], F[rev[i]]);
    	int cnt = 1;
    	for (int l = 2; l <= up; l <<= 1) {
    		int h = l >> 1, w = (ty > 0) ? g[cnt] : ig[cnt];
    		for (int b = 0; b < up; b += l) {
    			int wi = 1;
    			for (int p = b; p < b + h; ++p) {
    				int tt = ml(F[p + h], wi);
    				F[p + h] = dc(F[p], tt);
    				F[p] = ad(F[p], tt);
    				wi = ml(wi, w);
    			}
    		}
    		++cnt;
    	}
    	if (ty < 0) {
    		int tt = ksm(up, Mod - 2);
    		for (int i = 0; i < up; ++i) F[i] = ml(F[i], tt);
    	}
    }
    void Inv(const int *F, int *G, int up) {
    	if (up == 1) {
    		G[0] = ksm(F[0], Mod - 2);
    		return ;
    	}
    	Inv(F, G, up >> 1);
    	Clear(G, up >> 1, up << 1);
    	static int T[N];
    	Copy(T, F, 0, up);
    	Clear(T, up, up << 1);
    	GetRev(up << 1);
    	NTT(T, up << 1, 1);
    	NTT(G, up << 1, 1);
    	for (int i = 0; i < (up << 1); ++i)
    		G[i] = dc(ml(2, G[i]), ml(ml(G[i], G[i]), T[i]));
    	NTT(G, up << 1, -1);
    }
    void Der(int *F, int up) {
    	for (int i = 0; i <= up - 2; ++i)
    		F[i] = ml(F[i + 1], i + 1);
    	F[up - 1] = 0;
    }
    void Int(int *F, int up) {
    	for (int i = up - 2; i >= 0; --i)
    		F[i + 1] = ml(F[i], ksm(i + 1, Mod - 2));
    	F[0] = 0;
    }
    void Ln(const int *F, int *G, int up) {
    	static int T[N];
    	Copy(T, F, 0, up);
    	Der(T, up);
    	Inv(F, G, up);
    	Clear(G, up, up << 1);
    	Clear(T, up, up << 1);
    	NTT(G, up << 1, 1);
    	NTT(T, up << 1, 1);
    	for (int i = 0; i < (up << 1); ++i)
    		G[i] = ml(G[i], T[i]);
    	NTT(G, up << 1, -1);
    	Int(G, up);
    }
    int n, A[N], B[N], fac[N];
    int main() {
    	Init();
    	scanf("%d", &n);
    	fac[0] = 1;
    	for (int i = 1; i <= n; ++i) fac[i] = ml(fac[i - 1], i);
    	A[0] = 1;
    	A[1] = 1;
    	for (int i = 2; i <= n; ++i) A[i] = ml(ksm(2, (ll) i * (i - 1ll) / 2ll), ksm(fac[i], Mod - 2));
    	Ln(A, B, GetUp(n));
    	printf("%d
    ", ml(B[n], fac[n]));
    	return 0;
    }
    
  • 相关阅读:
    redis_String
    redis单线程架构
    redis数据结构与内部编码
    常用命令
    Tomcat:web服务器软件
    mysql数据库-备份与还原实操
    mysql数据库-备份方式简介与规范
    mysql数据库-日志管理
    mysql数据库-简介
    在 Kubernetes 集群在线部署 KubeSphere
  • 原文地址:https://www.cnblogs.com/skiceanAKacniu/p/13276766.html
Copyright © 2011-2022 走看看