题目传送门

题目大意:有$n$个小岛,每个小岛上有$a_{i}$个城市,同一个小岛上的城市互相连接形成一个完全图,第$i$个小岛的第$a_{i}$个城市和第$i+1$个小岛的第$1$个城市连接,特别地,第$n$个小岛的第$a_{n}$个城市和第$1$个小岛的第$1$个城市连接。现在要断掉图中的一些边,保证任意两个城市只有一条路径或者不连通,求合法的断边方案总数,$n,a_{i}<=1e5$

完全不会(喷血

我们对每个小岛单独讨论

如果任意两个城市只有一条路径或者不连通,那么这张图只能是一个森林

定义$f[i]$表示$i$个点的完全图的答案

我们对第$i$个点所在的树进行讨论, 设$i$点所在的树除了$i$点还有$j$个节点,可以得到方程

$f[i]=\sum\limits_{j=0}^{i-1} C_{i-1}^{j}f[i-j-1](j+1)^{j-1}$

完全图有标号生成树个数是$n^{n-2}$

把上述式子展开,发现是一个卷积形式,可以用分治$NTT$求解

显然小岛间的边至少断一条就ok了

如果一条都不断边呢?

就要保证至少一个小岛内的$1$号点和$a_{i}$号点不连通

我们去掉每个小岛的$1$号点和$a_{i}$号点都连通的方案数就行了

这种情况的$DP$方程和上面的差不多, 设$i$点所在的树除了$i$点和$1$号点还有$j$个节点

$g[i]=\sum\limits_{j=0}^{i-2} C_{i-1}^{j-1}f[i-j-2](j+2)^{j}$

不用分治直接$NTT$就行了

 #include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 (1<<18)+10
#define il inline
#define dd double
#define ld long double
#define ll long long
using namespace std; const int inf=0x3f3f3f3f;
const ll p=;
int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
ll qpow(ll x,ll y)
{
ll ans=;
for(;y>;x=x*x%p,y>>=) if(y&) ans=ans*x%p;
return ans;
} int T,n,m;
namespace NTT{
ll a[N1],b[N1],c[N1],Wn[N1],_Wn[N1];
int r[][N1];
void Pre(int len,int L)
{
int i,j;
for(j=;j<=L;j++) for(i=;i<(<<j);i++)
r[j][i]=(r[j][i>>]>>)|((i&)<<(j-));
for(i=;i<=len;i<<=) Wn[i]=qpow(,(p-)/i), _Wn[i]=qpow(Wn[i],p-);
}
void NTT(ll *s,int len,int type,int L)
{
int i,j,k; ll wn,w,t;
for(i=;i<len;i++) if(i<r[L][i]) swap(s[i],s[r[L][i]]);
for(k=;k<=len;k<<=)
{
wn=(type>)?Wn[k]:_Wn[k];
for(i=;i<len;i+=k)
{
for(j=,w=;j<(k>>);j++,w=w*wn%p)
{
t=w*s[i+j+(k>>)]%p;
s[i+j+(k>>)]=(s[i+j]+p-t)%p;
s[i+j]=(s[i+j]+t)%p;
}
}
}
}
void Main(int len,int L)
{
int i,invl=qpow(len,p-);
NTT(a,len,,L); NTT(b,len,,L);
for(i=;i<len;i++) c[i]=a[i]*b[i]%p;
NTT(c,len,-,L);
for(i=;i<len;i++) c[i]=c[i]*invl%p;
}
void clr(int sz)
{
memset(a,,sz<<);
memset(b,,sz<<);
}
}; using NTT::a; using NTT::b; using NTT::c;
ll F1[N1],F2[N1],f[N1],g[N1],mul[N1],_mul[N1];
void CDQ(int l,int r)
{
if(r-l==&&l)
{
F1[l]=(f[l]*mul[l-]%p+qpow(l,l-))%p;
f[l]=F1[l]*_mul[l]%p;
}
if(r-l<=) return;
int mid=(l+r)>>,i,len,L;
CDQ(l,mid);
for(len=,L=;len<(mid-l)+(r-l)-;len<<=,L++);
for(i=l;i<mid;i++) NTT::a[i-l]=f[i];
for(i=;i<(r-l);i++) NTT::b[i]=g[i];
NTT::Main(len,L);
for(i=mid;i<r;i++) f[i]=(f[i]+NTT::c[i-l])%p;
NTT::clr(len);
CDQ(mid,r);
}
int v[][N1],sz[]; int main()
{
scanf("%d",&T);
int i,j,x,y,len,L,t;
for(t=;t<T;t++)
{
sz[t]=gint();
for(i=;i<=sz[t];i++) v[t][i]=gint(), n=max(n,v[t][i]);
}
for(len=,L=;len<n+n-;len<<=,L++);
NTT::Pre(len,L);
mul[]=mul[]=_mul[]=_mul[]=;
for(i=;i<=n;i++) mul[i]=mul[i-]*i%p, _mul[i]=qpow(mul[i],p-);
for(i=,g[]=;i<=n;i++) g[i]=qpow(i,i-)*_mul[i-]%p;
CDQ(,n+);
for(i=;i<=n;i++) NTT::a[i]=F1[i]*_mul[i]%p; NTT::a[]=; // f[j] / (j-1)!
for(i=;i<=n;i++) NTT::b[i]=qpow(i,i-)*_mul[i-]%p; // j^(j-2) / (j-2)! NTT::b[1]=1;
NTT::Main(len,L); F2[]=;
for(i=;i<=n;i++) F2[i]=mul[i-]*NTT::c[i]%p;
for(t=;t<T;t++)
{
ll ans=qpow(,sz[t]),ret=;
for(i=;i<=sz[t];i++) ans=ans*F1[v[t][i]]%p;
for(i=;i<=sz[t];i++) ret=ret*F2[v[t][i]]%p;
ans=(ans+p-ret)%p;
printf("%lld\n",ans);
}
return ; }

HDU 5279 YJC plays Minecraft (分治NTT优化DP)的更多相关文章

  1. HDU 5279 YJC plays Minecraft(NTT+分治)

    题意 有 \(n\) 个岛屿,第 \(i\) 个岛屿上有一张 \(a_i\) 的完全图.其中第 \(i\) 张完全图的 \(a_i\) 号节点和 \(i+1\) 号岛屿的 \(1\) 号节点有边相连( ...

  2. hdu 5279 YJC plays Minecraft——生成函数

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5279 令 n 个点的树的 EGF 是 g(x) ,则 \( g(x) = \sum\limits_{i=0 ...

  3. 题解 HDU 5279 YJC plays Minecraft

    题目传送门 题目大意 给出\(n\)以及\(a_{1,2,...,n}\),表示有\(n\)个完全图,第\(i\)个完全图大小为\(a_i\),这些完全图之间第\(i\)个完全图的点\(a_i\)与\ ...

  4. ZOJ 3874 Permutation Graph (分治NTT优化DP)

    题面:vjudge传送门 ZOJ传送门 题目大意:给你一个排列,如果两个数构成了逆序对,就在他们之间连一条无向边,这样很多数会构成一个联通块.现在给出联通块内点的编号,求所有可能的排列数 推来推去容易 ...

  5. HDU 5322 Hope (分治NTT优化DP)

    题面传送门 题目大意: 假设现在有一个排列,每个数和在它右面第一个比它大的数连一条无向边,会形成很多联通块. 定义一个联通块的权值为:联通块内元素数量的平方. 定义一个排列的权值为:每个联通块的权值之 ...

  6. 【uoj#244】[UER #7]短路 CDQ分治+斜率优化dp

    题目描述 给出 $(2n+1)\times (2n+1)$ 个点,点 $(i,j)$ 的权值为 $a[max(|i-n-1|,|j-n-1|)]$ ,找一条从 $(1,1)$ 走到 $(2n+1,2n ...

  7. BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)

    BZOJ1492:[NOI2007]货币兑换 题目传送门 [问题描述] 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和B纪念券(以下简称B券).每个持有金券的 ...

  8. hdu5279 YJC plays Minecraft 【分治NTT】

    题目链接 hdu5279 题解 给出若干个完全图,然后完全图之间首尾相连并成环,要求删边使得两点之间路径数不超过\(1\),求方案数 容易想到各个完全图是独立的,每个完全图要删成一个森林,其实就是询问 ...

  9. HDU 2993 MAX Average Problem(斜率优化DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 题目大意:给定一个长度为n(最长为10^5)的正整数序列,求出连续的最短为k的子序列平均值的最大 ...

随机推荐

  1. 【ACM】hdu_zs2_1005_Problem E _201308030747

    Problem E Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)Total Subm ...

  2. owin-startup方法

    owin在根目录下有这个startup.cs文件,里面有个startup方法,这个和global.asax有什么区别呢? 测试一下执行顺序,是先执行了global.asax文件,再执行了startup ...

  3. [MySQLCPU]线上飙升800%,load达到12的解决过程

    接到报警通知,负载过高,达到800%,load也过高,有11了. MySQL版本为5.6.12-log 1 top 之后,确实是mysqld进程占据了所有资源. 2 查看error日志,无任何异常 3 ...

  4. UVa 10290 - {Sum+=i++} to Reach N

    题目:给你一个数字问将他写成连续的数字的和的形式.有几种写法. 分析:数论. 设拆成的序列个数为k,我们分两种情况讨论: 1.拆成奇数个连续数.那么设中位数是a,则有n = k * a: 2.拆成偶数 ...

  5. 【CSS】隐藏多行文本框Textarea在IE中的垂直滚动栏

    在<[CSS]禁止Google浏览器同意定义调整多行文本框>(点击打开链接)中已经提及过怎样使多行文本框Textarea在一些DOM2的浏览器中固定下来. 这不,多行文本框Textarea ...

  6. 屏幕測试亮点,新买了一个显示器,使用web简单的測试下了亮点

    1,购买了一个新的显示器 趁着双11的时候价格廉价.入手了一个显示器. http://serve.netsh.org/pub/dead_pixel.bin 滚动下就能够换颜色了.把chrome最大化, ...

  7. SQL Server数据库 bcp导出备份文件应用

    /**  * 授权  */ EXEC sp_configure 'show advanced options',1; go reconfigure; go exec sp_configure 'xp_ ...

  8. vim插件系列

    http://foocoder.com/blog/mei-ri-vimcha-jian-ping-hua-gun-dong-accelerated-smooth-scroll-dot-vim.html ...

  9. 【POJ 3700】 Missile Defence System

    [题目链接] http://poj.org/problem?id=3700 [算法] 对于每一枚导弹,有4种决策 : 1.新建一套递增的系统拦截它 2.新建一套递减的系统拦截它 3.在已经建好的递增拦 ...

  10. python程序中用类变量代替global 定义全局变量

    在python编程中,一般使用global 关键字来定义全局变量,但是发现 global 关键字在涉及多个文件时,好像存在问题. 比如,单个文件下用global定义使用全局变量的情况 ,看下面的代码 ...