题意

有 \(n\) 个球球,每个球球有一个属性值 。一个合法的排列满足不存在相邻两个球球的属性值乘积是完全平方数。求合法的排列数量对 \(10^9+7\) 取膜。

\(n\le 300\) (本题数据范围可扩大至 \(n\le 3000\)) 。

题解

首先很显然,如果 \(xy,yz\) 是完全平方数,那么 \(xz\) 也是完全平方数。这样我们可以将球球分成若干组,每组的两两乘积都是完全平方数。

那么问题转化为有若干球球,每个球球一个颜色,求满足相同颜色的球球不相邻的排列数。

下设 \(a_i\) 为第 \(i\) 种颜色的球球个数, \(m\) 为颜色个数。

我们考虑容斥。我们将连续颜色相同的小球球合并成一个大球球,设 \(b_i\) 为 合并后第 \(i\) 种颜色的球球的数量,那么答案即为 \(b\) 的可重排列数乘上每种颜色内部排列数 \(\displaystyle \frac{(\sum_{i=1}^mb_i)!}{\prod_{i=1}^mb_i!} \cdot \prod_{i=1}^m a_i!\) ,容斥系数用插板法计算,为 \(\displaystyle \prod_{i=1}^m (-1)^{a_i-b_i} \cdot \binom{a_i-1}{b_i-1}\) 。

考虑如何计算这个式子。设 \(s=\sum_{i=1}^m b_i\) ,那么答案式子可转化为:

\[(-1)^{n-s} s!\prod_{i=1}^{m}\frac{\binom{a_i-1}{b_i-1}\cdot a_i!}{b_i!}
\]

我们考虑用 dp 计算后半部分式子。设 \(f(i,j)\) 表示前 \(i\) 个数, \(\sum_{x=1}^i b_x=j\) 的方案数。枚举 \(b_i=k\) 转移:

\[f(i,j)=\sum_{k=1}^{\min(a_i,j)}f(i-1,j-k)\cdot \frac{\binom{a_i-1}{k-1}\cdot a_i!}{k!}
\]

最后按上面的式子枚举 \(s\) 容斥统计答案即可。

dp 的复杂度看上去像 \(n^3\) ,实际上理性分析,复杂度为 \(\sum_{i=1}^n a_i (\sum_{j=1}^i a_j) =O(n^2)\) .

code

#include<cstdio>
#include<cmath>
typedef long long ll;
const int N=305,Mod=1e9+7;
int t[N],a[N],f[N][N],n,m,fac[N],inv[N],ans,v;
inline int mul(int x, int y) {
return 1ll*x*y%Mod;
}
inline int po(int x, int y)
{
int r=1;
while(y)
{
if(y&1) r=mul(r,x);
x=mul(x,x), y>>=1;
}
return r;
}
inline int C(int x, int y) {
return mul(mul(fac[x],inv[y]),inv[x-y]);
}
int main()
{
scanf("%d",&n);
for(int i=1,x,j;i<=n;++i)
{
scanf("%d",&x);
for(j=1;j<=m;++j)
if(1ll*t[j]*x==(ll)sqrt(1ll*t[j]*x)*(ll)sqrt(1ll*t[j]*x))
{
++a[j];
break;
}
if(j>m) t[++m]=x,++a[m];
}
fac[0]=inv[0]=1;
for(int i=1;i<=n;++i) fac[i]=mul(fac[i-1],i);
inv[n]=po(fac[n],Mod-2);
for(int i=n-1;i;--i) inv[i]=mul(inv[i+1],i+1);
int ans=0,v=0;
f[0][0]=1;
for(int i=1;i<=m;++i)
{
v+=a[i];
for(int j=1;j<=v;++j)
for(int k=1;k<=a[i]&&k<=j;++k)
f[i][j]=(f[i][j]+mul(f[i-1][j-k],mul(C(a[i]-1,k-1),inv[k])))%Mod;
}
for(int i=1;i<=n;++i)
{
int t=mul(fac[i],f[m][i]);
(n-i&1)?ans=(ans+Mod-t)%Mod:ans=(ans+t)%Mod;
}
for(int i=1;i<=m;++i) ans=mul(ans,fac[a[i]]);
printf("%d",ans);
}

【Luogu4448】 [AHOI2018初中组]球球的排列的更多相关文章

  1. TYVJ4623 球球大作战·生存

    时间: 500ms / 空间: 65536KiB / Java类名: Main 背景 小天很喜欢玩球球大作战这个游戏,大家也应该都玩过.游戏规则是:移动自己的球,移动到别人的球(一定要比自己的球小)的 ...

  2. 【204】显示3D大球球

    1. 光滑球  From Jan 28, 2016    2. 大球球 https://www.revolvermaps.com/?target=enlarge&i=0xoqkxnu52c&a ...

  3. java实现简单窗体小游戏----球球大作战

    java实现简单窗体小游戏----球球大作战需求分析1.分析小球的属性: ​ 坐标.大小.颜色.方向.速度 2.抽象类:Ball ​ 设计类:BallMain—创建窗体 ​ BallJPanel—画小 ...

  4. Creator3D 守护你的球球—UV动画与天空盒

    1 游戏预览 在线体验地址:http://example.creator-star.cn/follo-ball/ 2 场景物体 场景物体 新建场景后,引擎会为我们创建默认的摄像机和灯光,这个我们就不介 ...

  5. 第四届西安邮电大学acm-icpc校赛 猜球球

    题目描述 六一到了,为了庆祝这个节日,好多商家都推出了很多好玩的小游戏.Tongtong看到了一个猜球球的游戏,有n种除了颜色之外完全相同的球,商家从中拿出来一个球球放到了箱子里,已知第i种颜色的球出 ...

  6. luogu P4448 [AHOI2018初中组]球球的排列

    这道题我一上来只会80 还是要感谢题解区大佬题解的帮助 先考虑若\(xy,xz\)为完全平方数,则\(yz\)也为完全平方数,因为\(xy*xz=x^2yz\)为完全平方数,除掉\(x^2\)就行了 ...

  7. js实现动态球球背景

    document.getElementsByTagName("body")[0].style.backgroundColor="#000" //构造函数 fun ...

  8. [ACM] 1007 -球球方格

    与兔子方格类似,不过一秒走一格: 输入 代码 #include<iostream> using namespace std; int main(void) { int test_count ...

  9. hdoj薛猫猫杯程序设计网络赛1003 球球大作战

    思路: 二分,check函数不是很好写. 实现: 1. #include <bits/stdc++.h> using namespace std; typedef long long ll ...

随机推荐

  1. Cisco AP-格式化AP

    故障情况:APC11-AP04#sho capwap ip config LWAPP Static IP ConfigurationIP Address         172.17.239.204I ...

  2. 使用注解配置Servlet3.0

    从Servlet3.0开始支持使用注解来配置. 注解只是代替了一部分的web.xml的 配置,通常在针对单个Servlet的配置时(比如Servlet的资源名称)使用注解 web.xml:优势在于解决 ...

  3. 【PAT甲级】1066 Root of AVL Tree (25 分)(AVL树建树模板)

    题意: 输入一个正整数N(<=20),接着输入N个结点的值,依次插入一颗AVL树,输出最终根结点的值. AAAAAccepted code: #define HAVE_STRUCT_TIMESP ...

  4. 树莓派4B踩坑指南 - (8)安装GO语言

    下载 191129最新版本为go1.13.4.linux-armv6l.tar.gz go官网(点此访问)国内访问似乎不是很稳定,但下载速度还挺快,下载地址:(点此访问) 安装 解压后是一个名为go的 ...

  5. knockout 简单使用

    定义: var QcViewModel = function () { var self = this; self.name = ko.observable(); self.qty = ko.obse ...

  6. 基于Struts2+Hibernate开发小区物业管理系统 附源码

    开发环境: Windows操作系统开发工具: MyEclipse+Jdk+Tomcat+MySql数据库 运行效果图: 源码及原文链接:https://javadao.xyz/forum.php?mo ...

  7. iOS中常用的手势

    --前言 智能手机问世后的很长一段时间,各大手机厂商都在思考着智能手机应该怎么玩?也都在尝试着制定自己的一套操作方式.直到2007年乔布斯发布了iPhone手机,人们才认识到智能手机就应该这样玩. 真 ...

  8. 投资人分享答疑----HHR计划----以太直播课第三课

    分享大纲:(祥峰投资) 一,投资人会看什么: 1,赛道定位:“生意”还是“独角兽-to be”? 2,如何退出?上市还是收购? 3,  团队能力,愿景力 4,壁垒:数据和价值 5,价格 二,融资需要准 ...

  9. selenium+chrome options

    selenium+chrome options 环境:selenium chrome 1.      selenium + chrome参数配置 1.1.    启动 from selenium im ...

  10. 【转载】手把手教你使用Git(简单,实用)

    手把手教你使用Git(简单,实用) 标签: git 2016年04月21日 20:51:45 1328人阅读 评论(0) 收藏 举报 一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. ...