题目描述

题解:

岛屿之间的边砍/不砍情况有$2^n$种,

但是需要剪掉所有的岛上都首尾相连的情况。

$dp$一下对于完全图没有限制($f$)/有限制($g$)的情况数。

方程:$$f[i]=\sum(C(i-1,j-1)*j^{(j-2)}*f[i-j])$$

$$g[i]=\sum(C(i-2,j-2)*j^{(j-2)}*f[i-j])$$

其中$j^(j-2)$是$j$个点的完全图的生成树个数。

打开组合数之后$CDQ$即可。

统计答案时$ans=2^n*\prod(f)-\prod(g)$。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MOD = ;
const int N = ;
typedef long long ll;
template<typename T>
inline void read(T&x)
{
T f = ,c = ;char ch = getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){c=c*+ch-'';ch=getchar();}
x = f * c;
}
ll fastpow(ll x,int y)
{
ll ret = ;
while(y)
{
if(y&)ret= ret*x%MOD;
x= x*x % MOD;
y>>=;
}
return ret;
}
int to[*N],lim=,L;
ll W[*N],inv;
void ntt(ll *a,int len,int k)
{
for(int i=;i<len;i++)
if(i<to[i])swap(a[i],a[to[i]]);
for(int i=;i<len;i<<=)
{
ll w0 = W[i];
for(int j=;j<len;j+=(i<<))
{
ll w = ;
for(int o=;o<i;o++,w=w*w0%MOD)
{
ll w1 = a[j+o],w2 = a[j+o+i]*w%MOD;
a[j+o] = (w1+w2)%MOD;
a[j+o+i] = (w1-w2+MOD)%MOD;
}
}
}
if(k==-)
{
for(int i=;i<(len>>);i++)swap(a[i],a[len-i]);
for(int i=;i<len;i++)a[i]=a[i]*inv%MOD;
}
}
ll a[*N],b[*N],c[*N],d[*N],e[*N];
ll f[N],g[N],fj[N],gj[N],jc[N],jn[N];
void clear()
{
for(int i=;i<lim;i++)a[i]=b[i]=;
}
void work()
{
ntt(a,lim,),ntt(b,lim,),ntt(c,lim,);
for(int i=;i<lim;i++)d[i]=a[i]*b[i]%MOD,e[i]=a[i]*c[i]%MOD;
ntt(d,lim,-),ntt(e,lim,-);
}
void cdq(int l,int r)
{
if(l==r)
{
if(l==)f[l] = ;
else f[l] = f[l]*jc[l-]%MOD;
if(l<=)g[l] = ;
else g[l] = g[l]*jc[l-]%MOD;
return ;
}
int mid = (l+r)>>;
cdq(l,mid);
lim = ,L = ;
while(lim<=(r-l+))lim<<=,L++;
for(int i=;i<lim;i++)to[i]=((to[i>>]>>)|((i&)<<(L-)));
inv = fastpow(lim,MOD-);
for(int i=;i<lim;i<<=)W[i]=fastpow(,(MOD-)/(i<<));
clear();
for(int i=;i<=mid-l;i++)a[i]=f[i+l]*jn[i+l]%MOD;
for(int i=;i<=r-l;i++)b[i]=fj[i],c[i]=gj[i];
work();
for(int i=mid-l+;i<=r-l;i++)f[i+l]=(f[i+l]+d[i])%MOD;
for(int i=mid-l+;i<=r-l;i++)g[i+l]=(g[i+l]+e[i])%MOD;
cdq(mid+,r);
}
int T,n,x;
int main()
{
jc[]=jn[]=;
fj[]=jc[]=jn[]=;
for(int i=;i<=;i++)
{
jc[i] = jc[i-] * i % MOD;
jn[i] = fastpow(jc[i],MOD-);
ll tmp = fastpow(i,i-);
fj[i] = tmp*jn[i-]%MOD;
gj[i] = tmp*jn[i-]%MOD;
}
cdq(,);
read(T);
while(T--)
{
read(n);
ll s1=,s2=;
for(int i=;i<=n;i++)
{
read(x);
s1 = s1 * f[x]%MOD;
s2 = s2 * g[x]%MOD;
}
s1 = s1*fastpow(,n)%MOD;
printf("%lld\n",(s1-s2+MOD)%MOD);
}
return ;
}

hdu5279 YJC plays Minecraft的更多相关文章

  1. hdu5279 YJC plays Minecraft 【分治NTT】

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

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

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

  3. HDU 5279 YJC plays Minecraft (分治NTT优化DP)

    题目传送门 题目大意:有$n$个小岛,每个小岛上有$a_{i}$个城市,同一个小岛上的城市互相连接形成一个完全图,第$i$个小岛的第$a_{i}$个城市和第$i+1$个小岛的第$1$个城市连接,特别地 ...

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

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

  5. 题解 HDU 5279 YJC plays Minecraft

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

  6. CDQ题目套路总结 [未完成]

    CDQ学习资料 day1cdq分治相关 CDQ的IOI论文 1.优化斜率dp 左边对右边影响维护一个凸包解决 需要知识:①凸包②斜率dp 题目:√ HDU3842 Machine Works   HY ...

  7. MineCraft note

    客户端:http://pan.baidu.com/s/1hqgS8sshttp://pan.baidu.com/s/1mgmkduC 材质包:R3D小地图MODCraftGuide mod 内置合成表 ...

  8. Ubuntu上安装Minecraft服务器

    Minecraft由于其独特的魅力吸引了很多玩家.不过游戏的乐趣只有在和朋友一起玩的时候才最有意思,所以很早以前我就想建设自己的服务器.但由于专业知识欠缺,没有实现. 最近接触了Linux服务器,所以 ...

  9. 纵观minecraft 游戏作者的世界观

    minecraft 这款游戏 独特的游戏背景 与 模式 深受我爱 ,游戏的音乐制作方面也是独具一格 但是 整个游戏的风气 充满孤独的色彩 抑郁惆怅的音乐 每当在日出时 响起 ,当你进入生存模式之后 开 ...

随机推荐

  1. hdoj1160【DP】

    现在还很弱,贴一个我bin的结题报告日后写到一定会了加油 说说感觉,读题不读好,然后读完想不出,知道是dp不好好想,先排序一列,再求另一列,dp[ i ]代表长度,那么需要输出整个序列需要路径和一个标 ...

  2. bzoj 1023: [SHOI2008]cactus仙人掌图【tarjan+dp+单调队列】

    本来想先求出点双再一个一个处理结果写了很长发现太麻烦 设f[u]为u点向下的最长链 就是再tarjan的过程中,先照常处理,用最长儿子链和次长儿子链更新按ans,然后处理以这个点为根的环,也就是这个点 ...

  3. bzoj 3594: [Scoi2014]方伯伯的玉米田【二维树状数组+dp】

    设f[i][j]为前i棵玉米被拔高了j(因为是单调不降所以前面越高越好,所以每次拔一个前缀),转移是f[i][j]=f[k][l]+1,l<=j,a[k]+l<=a[i]+j,然后用二维树 ...

  4. 跟我一起玩Win32开发(7):多边形窗口

    通常情况下,窗口都是一个矩形,不过,调用下面这个函数,可以自定义窗口的形状. int SetWindowRgn( __in  HWND hWnd, __in  HRGN hRgn, __in  BOO ...

  5. 1-6static关键字

    static的作用? static可以修饰变量,被static修饰的变量叫做静态变量,程序运行时静态变量存放在方法区里面,因此,静态变量在类加载阶段赋值,并且只赋值一次.请看例1 static可以修饰 ...

  6. selenium2+python自动化2-元素定位

    嘻嘻,书接上回,接着唠,这里先补充一下自动化要掌握的四个步骤吧:获取元素.操作元素.获取返回值.断言(返回结果与期望结果是否一致),最后就是自动化测试报告的生成.这一片主要讲一下如何进行元素定位.元素 ...

  7. Linux下cpu过高问题排查

    原文地址:https://blog.csdn.net/chenjunan888/article/details/80447800 在服务器报cpu过高时,可使用以下命令,快速导出堆栈信息,以方便查看具 ...

  8. ISCSI存储

    slave-147作为服务端 需要安装的软件 [root@slave-147 ~]# yum install -y scsi-target-utils slave-148和slave-149作为客户端 ...

  9. oracle 触发器,序列,索引

    oracle 触发器,序列,索引 --1,触发器 ----trigger /*触发器是一种特殊的存储过程,它与数据表紧密联系,用于保护表中的数据, 当一个定义了特定类型触发器的基表执行插入.修改或删除 ...

  10. 【学习笔记】深入理解js原型和闭包(2)——函数和对象的关系

    上文(深入理解jS原型和闭包(1)——一切都是对象)已经提到,函数就是对象的一种,因为通过instanceof函数可以判断. var fn = function () { }; console.log ...