hdu 5552 Bus Routes

考虑有环的图不方便,可以考虑无环连通图的数量,然后用连通图的数量减去就好了。

无环连通图的个数就是树的个数,又 prufer 序我们知道是 $ n^{n-2} $ 其中又由于有 $ n-1 $ 个边,每个边可以涂色,所以总共无环的方案数量是 $ m^{n-1} n^{n-2} $

那么现在就要算连通图的数量了。这个不如不连通图的数量好算。

不连通图的数量怎么算呢,原本想的是容斥,但是貌似不好实现,看了题解发现一种神仙思路。考虑固定一个点,并且让这个点连出一个连通块,剩下的点随意连,必然不连通。并且由于最后图中一定有这个点,这样是可以不重不漏计算所有情况的。

考虑用 $ s(i) $ 表示 $ i $ 个点的的方案总数,就是 $ (m+1)^{\frac{n(n+1)}{2}} $ ,一共有 $ \frac{n(n+1)}{2} $ 个边,可以选择 $ m $ 种颜色的一种或者不要这个边。

考虑 $ f(i) $ 表示 $ i $ 个点的连通图的方案数。

$ f(n) = g(n) - \displaystyle\sum_{i=1}^n \binom{i-1}{n-1} f(i)g(n-i) $

这个看起来就很分治NTT

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <cstring>
  5. #define ll long long
  6. using namespace std;
  7. #define P 152076289
  8. #define MAXN (1 << 19) + 13
  9. int n , m;
  10. int a[MAXN];
  11. int Pow(int x,int y) {
  12. int res=1;
  13. while(y) {
  14. if(y&1) res=res*(ll)x%P;
  15. x=x*(ll)x%P,y>>=1;
  16. }
  17. return res;
  18. }
  19. int wn[2][MAXN];
  20. void getwn(int l) {
  21. for(int i=1;i<(1<<l);i<<=1) {
  22. int w0=Pow(106,(P-1)/(i<<1)),w1=Pow(106,P-1-(P-1)/(i<<1));
  23. wn[0][i]=wn[1][i]=1;
  24. for(int j=1;j<i;++j)
  25. wn[0][i+j]=wn[0][i+j-1]*(ll)w0%P,
  26. wn[1][i+j]=wn[1][i+j-1]*(ll)w1%P;
  27. }
  28. }
  29. int rev[MAXN];
  30. void getr(int l) { for(int i=1;i<(1<<l);++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<l-1); }
  31. void NTT(int *A,int len,int f) {
  32. for(int i=0;i<len;++i) if(rev[i]<i) swap(A[i],A[rev[i]]);
  33. for(int l=1;l<len;l<<=1)
  34. for(int i=0;i<len;i+=(l<<1))
  35. for(int k=0;k<l;++k) {
  36. int t1=A[i+k],t2=A[i+l+k]*(ll)wn[f][l+k]%P;
  37. A[i+k]=(t1+t2)%P;
  38. A[i+l+k]=(t1-t2+P)%P;
  39. }
  40. if( f == 1 ) for(int inv=Pow(len,P-2),i=0;i<len;++i) A[i]=A[i]*(ll)inv%P;
  41. }
  42. int f[MAXN];
  43. int A[MAXN] , B[MAXN];
  44. int J[MAXN] , invJ[MAXN] , s[MAXN];
  45. void CDQ(int *a,int *b,int l,int r){
  46. if( l == r ) { a[l] += s[l] , a[l] %= P; return; }
  47. int m = l + r >> 1;
  48. CDQ( a , b , l , m );
  49. int p = 1 , len = 0;
  50. while( p <= ( r - l + 1 ) * 2 ) p <<= 1 , ++ len;
  51. getr( len ) , getwn( len );
  52. for( int i = 0 ; i < p ; ++i ) A[i] = B[i] = 0;
  53. for( int i = l ; i <= m ; ++i ) A[i - l] = 1ll * a[i] * invJ[i - 1] % P;
  54. for( int i = 0 ; i <= r - l ; ++i ) B[i] = 1ll * s[i] * invJ[i] % P;
  55. NTT( A , p , 0 ) , NTT( B , p , 0 );
  56. for( int i = 0 ; i < p ; ++i ) A[i] = 1ll * A[i] * B[i] % P;
  57. NTT( A , p , 1 );
  58. for( int i = m + 1 ; i <= r ; ++i ) a[i] = ( a[i] - 1ll * J[i - 1] * A[i-l] % P + P ) % P;
  59. CDQ( a , b , m + 1 , r );
  60. }
  61. int kase = 0;
  62. signed main() {
  63. J[0] = invJ[0] = 1;
  64. for( int i = 1 ; i < MAXN ; ++ i )
  65. J[i] = 1ll * J[i - 1] * i % P , invJ[i] = Pow( J[i] , P - 2 );
  66. int T;cin >> T;
  67. while( T --> 0 ) {
  68. cin >> n >> m; m %= P;
  69. memset( f , 0 , sizeof f ) , memset( s , 0 , sizeof s );
  70. for( int i = 1 ; i <= n ; ++ i )
  71. s[i] = Pow( m + 1 , 1ll * i * ( i - 1 ) / 2 % ( P - 1 ) );
  72. f[0] = 1;
  73. CDQ( f , a , 0 , n );
  74. int x;
  75. printf("Case #%d: %d\n",++ kase,( f[n] - 1ll * Pow(n, n - 2) * Pow(m, n - 1) % P + P) % P);
  76. }
  77. }

hdu 5552 Bus Routes的更多相关文章

  1. HDU 5552 Bus Routes(NTT+分治)

    题意 给定 \(n\) 个点,任意连边,每条边有 \(m\) 种颜色可选,求带环连通图的方案数. \(1\leq n\leq 10000\) \(1\leq m < 2^{31}\) 思路 直接 ...

  2. HDU 5552 Bus Routes(2015合肥现场赛A,计数,分治NTT)

    题意  给定n个点,任意两点之间可以不连边也可以连边.如果连边的话可以染上m种颜色. 求最后形成的图,是一个带环连通图的方案数. 首先答案是n个点的图减去n个点能形成的树. n个点能形成的树的方案数比 ...

  3. URAL 1137 Bus Routes(欧拉回路路径)

    1137. Bus Routes Time limit: 1.0 secondMemory limit: 64 MB Several bus routes were in the city of Fi ...

  4. [LeetCode] Bus Routes 公交线路

    We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. For e ...

  5. [Swift]LeetCode815. 公交路线 | Bus Routes

    We have a list of bus routes. Each routes[i]is a bus route that the i-th bus repeats forever. For ex ...

  6. LeetCode解题报告—— Bus Routes

    We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. For e ...

  7. [LeetCode] 815. Bus Routes 公交路线

    We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. For e ...

  8. 【leetcode】815. Bus Routes

    题目如下: We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. ...

  9. HDU 3420 -- Bus Fair ACM

    Bus Fair Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

随机推荐

  1. 【UE4 设计模式】策略模式 Strategy Pattern

    概述 描述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法的变化不会影响到使用算法的客户. 套路 Context(环境类) 负责使用算法策略,其中维持了一 ...

  2. 【UE4】类的继承层级关系

  3. 微信小程序的支付流程

    一.前言 微信小程序为电商类小程序,提供了非常完善.优秀.安全的支付功能 在小程序内可调用微信的API完成支付功能,方便.快捷 场景如下图所示: 用户通过分享或扫描二维码进入商户小程序,用户选择购买, ...

  4. 2021北航敏捷软工Beta阶段评分与总结

    概述 Beta 阶段评分,按照之前的规则,主要组成部分为: 博客部分,基于 Beta 阶段博客的评分(每篇正规博客 10 分,每篇 Scrum5 分,评定方式类比往年) 评审部分,基于 Beta 阶段 ...

  5. OO第三单元——JML规格化设计

    OO第三单元--JML规格化设计 JML语言的理论基础以及应用工具链情况 理论基础 JML是对JAVA程序进行规格化设计的一种表示语言,是一种行为接口规格语言.JML整合了Java和JAVAdoc,并 ...

  6. Python ImportError: No module named '_tkinter', please install the python3-tk package

    ImportError: No module named '_tkinter', please install the python3-tk package 这个问题的原因是使用的python3环境内 ...

  7. Java线程的三种实现方法

    Java多线程详解 线程简介 多任务,多线程 多任务情况中,虽然可以完成,但是实际上,多任务的完成是由一个一个小任务的完成来实现的,也就是说在执行多任务时,不是同时执行多个任务,而是一个时间段内只完成 ...

  8. openstack 后期维护(四)--- 删除僵尸卷

    前言: 在长时间使用openstack之后,删除虚机后,经常会有因这样那样的问题,导致卷处于僵尸状态,无法删除! 状态一: 虚机已近删除,然而卷却挂在到了 None上无法删除 解决办法: 1.# ci ...

  9. 源码安装的应用 rpm 命令无法查询

    源码安装:一大堆源码文件,需要编译后才能使用(编译需要安装编译器 :yum install gcc) rpm 安装:redhat 官网或其它开源网站编译好发布,已经编译好的安装包,使用 rpm -iv ...

  10. 大白话讲解调用Redis的increment失败原因及推荐使用

    大家在项目中基本都会接触到redis,在spring-data-redis-2.*.*.RELEASE.jar中提供了两个Helper class,可以让我们更方便的操作redis中存储的数据.这两个 ...