首页 > 其他分享 >生成函数题

生成函数题

时间:2022-10-09 09:44:28浏览次数:45  
标签:frac 函数 int LL 生成 binom inv mod

城市规划

\[设G(n)表示n个点的有标号无向图数量,我们知道,G(n)=2^{\binom{n}{2}}\\ 设F(n)表示n个点的有标号无向联通图数量,显然\\ \text{我们枚举一号店所在的联通块大小,剩下部分是任意图,合起来就是n个点的有标号无向图个数,然后暴力拆二项式系数}\\ \begin{aligned} G(n)&=\sum_{i=1}^n{\binom{n-1}{i-1}F(i)G(n-i)}\\ 2^{\binom{n}{2}}&=\sum_{i=1}^n{\frac{(n-1)!}{(n-i)!(i-1)!}F(i)2^{\binom{n-i}{2}}}\\ \frac{2^{\binom{n}{2}}}{(n-1)!} &=\sum_{i=1}^n{\frac{2^{\binom{n-i}{2}}}{(n-i)!}\frac{F(i)}{(i-1)!}}\\ \end{aligned} \\ 设A(n)=\frac{2^{\binom{n}{2}}}{(n-1)!}\\ 设B(n)=\frac{2^{\binom{n}{2}}}{n!}\\ 设C(n)=\frac{F(n)}{(n-1)!}\\ A=B*C\\ C=A*B^{-1}\\ 我们做一遍多项式求逆,再乘上(n-1)!就可以求出f \]

代码

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 1004535809, G = 3, Gi = 334845270;
const int maxn = 8e5 + 5;
LL fsp(LL a, LL b = mod - 2)
{
	LL s = 1;
	while (b)
	{
		if (b & 1)
			s = s * a % mod;
		b >>= 1;
		a = a * a % mod;
	}
	return s;
}
int r[maxn];
void NTT(LL *a, int limit, int type)
{
	for (int i = 0; i < limit; i++)
		if (i < r[i])
			swap(a[i], a[r[i]]);
	for (int mid = 1; mid < limit; mid <<= 1)
	{
		LL Wn = fsp(type == 1 ? G : Gi, (mod - 1) / (mid << 1));
		for (int j = 0; j < limit; j += (mid << 1))
		{
			LL w = 1;
			for (int k = 0; k < mid; k++, w = Wn * w % mod)
			{
				LL x = a[j + k], y = w * a[j + k + mid] % mod;
				a[j + k] = (x + y) % mod;
				a[j + k + mid] = (x - y + mod) % mod;
			}
		}
	}
}
LL a[maxn], x[maxn], y[maxn];
LL b[2][maxn];
void mul(LL *a, LL *b, LL *ans, int n, int m)
{
	memset(x, 0, sizeof(x));
	memset(y, 0, sizeof(y));
	for (int i = 0; i <= n; i++)
		x[i] = a[i];
	for (int i = 0; i <= m; i++)
		y[i] = b[i];
	LL limit = 1, L = 0;
	while (limit <= n + m)
		limit <<= 1, L++;
	for (int i = 0; i < limit; i++)
		r[i] = (r[i >> 1] >> 1) | ((i & 1) << (L - 1));
	NTT(x, limit, 1), NTT(y, limit, 1);
	for (int i = 0; i < limit; i++)
		ans[i] = x[i] * y[i] % mod;
	NTT(ans, limit, -1);
	LL inv = fsp(limit);
	for (int i = 0; i < limit; i++)
		ans[i] = ans[i] * inv % mod;
}
void invv(LL *a, LL *ans,int n)
{
	int bas = 1;
	int cur = 0;
	b[cur][0] = fsp(a[0]);
	while (bas <= (n << 1))
	{
		cur ^= 1;
		memset(b[cur], 0, sizeof(b[cur]));
		for (int i = 0; i < bas; i++)
		{
			b[cur][i] = (b[cur^ 1][i ] << 1) % mod;
		}
		mul(b[cur ^ 1], b[cur ^ 1], b[cur ^ 1], bas, bas);
		mul(b[cur ^ 1], a, b[cur ^ 1], bas, bas);
		for (int i = 0; i < bas; ++i)
			b[cur][i] = (b[cur][i] - b[cur ^ 1][i]+mod) % mod;
		bas <<= 1;
	}
    for(int i=0;i<=n;i++)ans[i]=b[cur][i];
}
LL fac[maxn],inv[maxn];
LL A[maxn],B[maxn],D[maxn];
LL C(int n,int m){
    if(m>n)return 0;
    return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{   
    fac[0]=inv[0]=1;
    for(int i=1;i<=200000;i++){
        fac[i]=fac[i-1]*i%mod;
        inv[i]=fsp(fac[i]);
    }
	int n;
	cin >> n;
    D[0]=1;
	for (int i = 1; i <= n; i++)
	{
		A[i]=fsp(2,(1ll*i*(i-1)/2)%(mod-1))*inv[i-1]%mod;
        D[i]=fsp(2,(1ll*i*(i-1)/2)%(mod-1))*inv[i]%mod;
	}
	invv(D,D,n);
	for(int i=n+1;i<=maxn-100;i++)D[i]=0;
    mul(A,D,B,n,n);
    cout<<B[n]*fac[n-1]%mod;
	return 0;
}

标签:frac,函数,int,LL,生成,binom,inv,mod
From: https://www.cnblogs.com/artalter/p/16771070.html

相关文章

  • 为什么需要拷贝构造函数
    把参数传递给函数有三种方法,一种是传值,一种是传地址,一种是传引用。传值与其他两种方式不同的地方在于当使用传值方式的时候,会在函数里面生成传递参数的一个副本,这个副本......
  • spring boot项目使用mybatis-plus代码生成实例
    前言mybatis-plus官方地址https://baomidou.commybatis-plus是mybatis的增强,不对mybatis做任何改变,涵盖了代码生成,自定义ID生成器,快速实现CRUD,自动分页,逻辑删除等功......
  • 网络字节序与主机字节序的转换函数
    1.字节序字节序是处理器架构特性,用于指示像整数这样的大数据类型内部的字节如何排序。简单来说,就是指超过一个字节的数据类型在内存中的存储的顺序。那么很明显,像char这......
  • 02#对数函数:换底公式
    什么是换底公式有一个对数logab,把a的底数换成c,那么就有logcb/logca,这个过程就叫作换底。新的底数c可以是10、5、e等,具体的情况要根据题目要求来决定。换底公式在......
  • leetcode 22 括号生成 js 实现
    22.括号生成难度中等数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合示例1:输入:n=3输出:["((()))","(()())","(()......
  • 01#对数函数:认识 log 函数
    什么是对数对数用log符号来表示。根据底数的不同,log可以变换成lg、ln。lg是以10为底的对数,ln是以e为底的对数。对数长成下面这个样子,是一个以a为底,y为真数......
  • 最小生成树
    kruskal1.建立并查集,初始每个点为一个集合。2.每次找到剩余的最短边加入并查集。#include<bits/stdc++.h>usingnamespacestd;intn,m;intans;intf[100086];st......
  • 网络字节序与主机字节序的转换函数实践
    首先介绍什么是网络字节序和主机字节序网络字节序网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机......
  • 网络字节序与主机字节序的转换函数实践
    首先需要了解知识:1.字节序(1)小端字节序,数值低位存储在内存的低地址,高位存储在内存的高地址。(2)大端字节序,数值高位存储在内存的低地址,低位存储在内存的高地址。主机字......
  • Vue3组件库打包指南,一次生成esm、esm-bundle、commonjs、umd四种格式
    本文为Varlet组件库源码主题阅读系列第二篇,读完本篇,你可以了解到如何将一个Vue3组件库打包成各种格式上一篇里提到了启动服务前会先进行一下组件库的打包,运行的命令为:v......