这道题我一上来只会80

还是要感谢题解区大佬题解的帮助

先考虑若\(xy,xz\)为完全平方数,则\(yz\)也为完全平方数,因为\(xy*xz=x^2yz\)为完全平方数,除掉\(x^2\)就行了

所以所有两两乘积为完全平方数的数可以放在一个集合中,用并查集合并即可.

若每个并查集都是一种颜色,所以现在问题变成有\(m\)种颜色的互不相同的球,每种颜色的球有\(b_i\)个,问多少种球的排列满足同色球不相邻

先把所有球按颜色大小排个序,然后考虑dp,设\(f[i][j][k]\)表示前\(i\)个球,有\(j\)个和\(i\)不同色且相邻的同色球对数,有\(k\)个和\(i\)同色且相邻的同色球对数的方案

如果当前球与上一个球不同色,那么考虑把这个球插入到同色球之间,方案为\(f[i-1][k][j-k+1]*(j+1)\)

插到异色球中,方案为\(f[i-1][k][j-k]*(i-j)\)

如果该球与上一个球颜色相同,这里先设\(cnt\)表示前面放了几个这样颜色的球

把这个球插到和这个球同色的球旁边,方案为\(f[i-1][j][k-1]*(cnt*2-(k-1))\)

插到其他同色球之间,方案为\(f[i-1][j+1][k]*(j+1)\)

插到其他异色球之间,方案为\(f[i-1][j][k]*(i-(cnt*2-k+j))\)

答案就是\(f[n][0][0]\)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<complex>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#define LL long long
#define il inline
#define re register using namespace std;
const LL mod=1000000007;
il LL rd()
{
re LL x=0,w=1;re char ch;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int n;
LL a[310],f[2][310][310];
int fa[310];
int findf(int x){return fa[x]==x?x:fa[x]=findf(fa[x]);}
void merg(int x,int y){fa[findf(y)]=findf(x);} int main()
{
n=rd();
for(int i=1;i<=n;i++) a[i]=rd(),fa[i]=i;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(findf(i)==findf(j)) continue;
LL mu=a[i]*a[j],sq=sqrt(mu);
if(sq*sq==mu) merg(i,j);
}
for(int i=1;i<=n;i++) a[i]=findf(i);
sort(a+1,a+n+1);
int now=1,la=0;
f[0][0][0]=1;
for(int i=1,cnt=0;i<=n;i++)
{
memset(f[now],0,sizeof(f[now]));
if(a[i]!=a[i-1])
{
cnt=0;
for(int j=0;j<i;j++)
{
for(int k=0;k<=j+1;k++)
{
if(k<=j) f[now][j][0]=(f[now][j][0]+(f[la][k][j-k]*(i-j))%mod)%mod;
f[now][j][0]=(f[now][j][0]+(f[la][k][j-k+1]*(j+1))%mod)%mod;
}
}
}
else
{
for(int j=0;j<i;j++)
for(int k=0;k<=cnt;k++)
{
if(k>0) f[now][j][k]=(f[now][j][k]+(f[la][j][k-1]*(cnt*2-(k-1)))%mod)%mod;
if(i-(cnt*2-k+j)>0) f[now][j][k]=(f[now][j][k]+(f[la][j][k]*(i-(cnt*2-k+j)))%mod)%mod;
f[now][j][k]=(f[now][j][k]+(f[la][j+1][k]*(j+1))%mod)%mod;
}
}
now^=1,la^=1;
++cnt;
}
printf("%lld\n",f[la][0][0]);
return 0;
}

luogu P4448 [AHOI2018初中组]球球的排列的更多相关文章

  1. 【Luogu4448】 [AHOI2018初中组]球球的排列

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

  2. TYVJ4623 球球大作战·生存

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

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

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

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

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

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

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

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

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

  7. luogu P4798 [CEOI2015 Day1]卡尔文球锦标赛 dp 数位dp

    LINK:卡尔文球锦标赛 可以先思考一下合法的序列长什么样子. 可以发现后面的选手可以使用前面出现的编号也可以直接自己新建一个队. 其实有在任意时刻i 序列的mex>max.即要其前缀子序列中1 ...

  8. js实现动态球球背景

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

  9. [ACM] 1007 -球球方格

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

随机推荐

  1. 重温Delphi之:面向对象

    任何一门语言,只要具备了"封装,继承,多态"这三项基本能力,不管其实现方式是直接或曲折.复杂或简洁,就可以称之为“面向对象”的语言. Delphi当年的迅速走红,是以其RAD快速开 ...

  2. Linux(Debian) 上安装tomcat并注册服务开机自启动

    1.准备工作 a.下载tomcat linux的包,地址:http://tomcat.apache.org/download-80.cgi,我们下载的版本是8.0,下载方式如图:          b ...

  3. 优步加入Linux基金会:支持开源

    导读 当地时间11月16日,优步在Uber Open Summit 2018年度峰会上宣布加入Linux基金会,并作为金级会员坚定支持对开源工具的使用和贡献. 优步CEO Thuan Pham将Lin ...

  4. MyBatis:传参

    MyBatis从入门到放弃二:传参 前言 我们在mapper.xml写sql,如果都是一个参数,则直接配置parameterType,那实际业务开发过程中多个参数如何处理呢? 从MyBatis API ...

  5. Spark_RDD之RDD操作简介

    1.转化操作 转化操作是返回一个新的RDD的操作,我们可以使用filter()方法进行转化.举个使用scala进行转化操作的例子. def main(args: Array[String]): Uni ...

  6. centos Install Mrtg

    安装支持软件包yum –y install gcc perl gd libpng zlib net-snmp mrtg配置snmpd编辑/etc/snmp/snmpd.conf文件备份snmpd.co ...

  7. Leetcode 217.存在重复元素 By Python

    给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: 输入: [1,2,3,1] 输出: true ...

  8. 自学Linux Shell10.1-使用编辑器vim

    点击返回 自学Linux命令行与Shell脚本之路 10.1-使用编辑器vim 所有的 Unix系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在.但是目前我们使用比较多的是 vim 编辑 ...

  9. emwin之2D图形绘制问题

    @2018-09-03 [问题] 在 WM_PAINT 消息分支里绘制2D图形可以正常显示,而在外部函数或按钮按下事件的响应消息分支下等处,绘制2D图形则不显示. [解决] 在除消息WM_PAINT分 ...

  10. bzoj1007/luogu3194 水平可见直线 (单调栈)

    先按斜率从小到大排序,然后如果排在后面的点B和前面的点A的交点是P,那B会把A在P的右半段覆盖掉,A会把B在P的左半段覆盖掉. 然后如果我们现在又进来了一条线,它跟上一条的交点还在上一条和上上条的左边 ...