当前位置: 首页 > article >正文

HDU5552 Bus Routes(分治NTT)

HDU5552 Bus Routes

题目大意

n n n个点, m m m种颜色,将 n n n个点连接起来,要求得到一个有环的连通图(没有重边和自环),同时可以对每条边染色。求有多少种方案?

输出答案模 152076289 152076289 152076289后的值。

T T T组数据。

1 < n ≤ 1 0 4 , 0 < m < 2 31 , T ≤ 200 1< n\leq 10^4,0< m< 2^{31},T\leq 200 1<n104,0<m<231,T200


题解

前置知识:分治FFT(NTT)

f ( n ) f(n) f(n)表示 n n n个点的连通图的染色方案总数, g ( n ) g(n) g(n)表示 n n n个点的图的染色方案总数, h ( n ) h(n) h(n)表示 n n n个点连接的树的染色方案总数,则

g ( n ) = ( m + 1 ) n ( n − 1 ) 2 g(n)=(m+1)^{\frac{n(n-1)}{2}} g(n)=(m+1)2n(n1)

g ( n ) g(n) g(n)的式子表示任意连边,连的边任意染色,不连的不染色。

h ( n ) = n n − 2 × m n − 1 h(n)=n^{n-2}\times m^{n-1} h(n)=nn2×mn1

h ( n ) h(n) h(n)的式子表示构成树方案的 n n − 2 n^{n-2} nn2 n − 1 n-1 n1条边任意染色就乘 m n − 1 m^{n-1} mn1

f ( n ) = g ( n ) − ∑ i = 1 n − 1 C n − 1 i − 1 × f ( i ) × g ( n − i ) = g ( n ) − ( n − 1 ) ! ∑ i = 1 n − 1 f ( i ) ( i − 1 ) ! g ( n − i ) ( n − i ) ! f(n)=g(n)-\sum\limits_{i=1}^{n-1}C_{n-1}^{i-1}\times f(i)\times g(n-i)=g(n)-(n-1)!\sum\limits_{i=1}^{n-1}\dfrac{f(i)}{(i-1)!}\dfrac{g(n-i)}{(n-i)!} f(n)=g(n)i=1n1Cn1i1×f(i)×g(ni)=g(n)(n1)!i=1n1(i1)!f(i)(ni)!g(ni)

枚举第一个点所在的连通块即可推出 f ( n ) f(n) f(n)的转移式。

用分治 N T T NTT NTT来解决,最后的答案为 f ( n ) − h ( n ) f(n)-h(n) f(n)h(n)

时间复杂度为 O ( T n log ⁡ 2 n ) O(Tn\log^2 n) O(Tnlog2n)

code

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=30000;
const long long G=106,mod=152076289;
long long ans,tmp,f[30005],g[30005],a1[30005],a2[30005];
long long jc[30005],ny[30005];
long long in(){
	long long re=0;
	char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9'){
		re=re*10+ch-'0';
		ch=getchar();
	}
	return re;
}
long long mi(long long t,long long v){
	long long re=1;
	while(v){
		if(v&1) re=re*t%mod;
		t=t*t%mod;
		v/=2;
	}
	return re;
}
void init(){
	jc[0]=1;
	for(int i=1;i<=N;i++) jc[i]=jc[i-1]*i%mod;
	ny[N]=mi(jc[N],mod-2);
	for(int i=N-1;i>=0;i--) ny[i]=ny[i+1]*(i+1)%mod;
}
void ch(long long *a,int l){
	for(int i=1,j=l/2,k;i<l-1;i++){
		if(i<j) swap(a[i],a[j]);
		k=l/2;
		while(j>=k){
			j-=k;k>>=1;
		}
		j+=k;
	}
}
void ntt(long long *a,int l,int fl){
	long long wn,w;
	for(int i=2;i<=l;i<<=1){
		if(fl==1) wn=mi(G,(mod-1)/i);
		else wn=mi(G,mod-1-(mod-1)/i);
		for(int j=0;j<l;j+=i){
			w=1;
			for(int k=j;k<j+i/2;k++,w=w*wn%mod){
				long long t=a[k],u=w*a[k+i/2]%mod;
				a[k]=(t+u)%mod;
				a[k+i/2]=(t-u+mod)%mod;
			}
		}
	}
	if(fl==-1){
		long long ny=mi(l,mod-2);
		for(int i=0;i<l;i++) a[i]=a[i]*ny%mod;
	}
}
void solve(int l,int r){
	if(l==r){
		f[l]=(f[l]+g[l])%mod;
		return;
	}
	int mid=l+r>>1;
	solve(l,mid);
	int len=1;
	while(len<r-l+1) len<<=1;
	
	for(int i=0;i<len;i++) a1[i]=a2[i]=0;
	for(int i=0;i<=mid-l;i++) a1[i]=f[i+l]*ny[i+l-1]%mod;
	for(int i=0;i<=r-l;i++) a2[i]=g[i]*ny[i]%mod;
	
	ch(a1,len);ch(a2,len);
	ntt(a1,len,1);ntt(a2,len,1);
	
	for(int i=0;i<len;i++){
		a1[i]=a1[i]*a2[i]%mod;
	}
	
	ch(a1,len);
	ntt(a1,len,-1);
	for(int i=mid+1;i<=r;i++){
		f[i]=(f[i]-jc[i-1]*a1[i-l]%mod+mod)%mod;
	}
	solve(mid+1,r);
}
int main()
{
	init();
	int t,n,m;
	t=in();
	for(int o=1;o<=t;o++){
		n=in();m=in();
		memset(f,0,sizeof(f));
		g[0]=1;
		for(int i=1;i<=n;i++) g[i]=mi(m+1,i*(i-1)/2);
		solve(1,n+1);
		ans=f[n];
		tmp=mi(n,n-2)*mi(m,n-1)%mod;
		ans=(ans-tmp+mod)%mod;
		printf("Case #%d: %lld\n",o,ans);
	}
	return 0;
}

http://www.kler.cn/news/17072.html

相关文章:

  • 每天一道算法练习题--Day16 第一章 --算法专题 --- ----------哈夫曼编码和游程编码
  • SpringCloud:ElasticSearch之数据同步
  • 【实例展示通俗易懂】SQL中的内外连接、左右连接
  • Vue3+Element Plus环境搭建和一键切换明暗主题的配置
  • 【Latex】有关于Latex tabularray的一些很不错的教程、模板
  • LeetCode周赛复盘(第343场周赛)
  • isNotBlank 和isNotEmpty的区别
  • 网络安全 等级保护 网络设备、安全设备知识点汇总
  • Nachos系统的上下文切换
  • Latex 定理和证明类环境(amsthm)和(ntheorm)的区别
  • 每日一题142——最少操作使数组递增
  • 【Linux超强学习路线图】赶紧收藏学习!
  • 数据库管理-第七十二期 复盘(20230505)
  • 【TCP为什么需要粘包和拆包】
  • LeetCode_双指针_中等_24.两两交换链表中的节点
  • 使用dataFEED OPC Suite将西门子PLC数据转发至REST API
  • FL Studio21没有language选项?如何设置切换中文语言
  • 《论文阅读》开放域对话摘要(长文本|知识嵌入)
  • 《花雕学AI》31:ChatGPT--用关键词/咒语/提示词Prompt激发AI绘画的无限创意!
  • 题目:16版.饲养员喂养动物
  • Mesh形变算法
  • git reset和git revert的区别
  • JDBC详解(三):使用PreparedStatement实现CRUD操作(超详解)
  • java基础入门-02-【面向对象】
  • Android开发 我的开源Android Log “日志狗”LogDog
  • 《通过十几轮数据进行模型训练,实现精确的无创血糖测量的演绎学习》阅读笔记
  • CC2642 读取和设置FEATURES
  • path/to/sdkmanager --install “cmdline-tools;latest“
  • k8s搭建教程
  • 内网渗透(六十一)之Kerberosating攻击