如果这不是一道原题,这道题出的还不错,是个比较毒瘤的数数。由于我太菜了反正我自己没有做出来后面的 dp,zyf 巨佬教的。

不过听说合肥六中某巨佬当年也没做出来,平衡了雾

但问题是这道题是原题,我安徽人什么时候可以真正站起来(恼

首先我们会发现这道题很不好入手,所以我们考虑部分分,很容易发现 6-8 测试点 \(a_i\) 全是质数。在这些测试点里面,我们只需要相邻两个球颜色不同即可。

我的数学老师说过,没有无缘无故的爱与恨,也没有无缘无故的部分分。所以我们考虑把 \(a_i\) 为合数的情况转化成 \(a_i\) 的情况。

这个时候就容易想到这个:如果 \(xy\) 为完全平方数,\(yz\) 为完全平方数,那么 \(xz\) 也是完全平方数。证明显而易见。这个引理告诉我们,如果 \(a_i\times a_j\) 为完全平方数,\(a_j \times a_k\) 为完全平方数,\(a_i \times a_k\) 也是完全平方数。也就是说这种数字不能放在一起。如果是更多个数字也是同理。

也就是说我们可以用暴力预处理出来哪些数不能放在一起,放在一个集合里,每个集合里的数有专属的颜色,那么我们的问题就是和 \(a_i\) 是质数的部分分的问题等价了:我们有 \(n\) 个球球 \(k\) 种颜色,第 \(i\) 个颜色有 \(s_i\) 个球,相同颜色的球不能放在一起,求方案数。

然后就是我没做出来的 dp((*/ω\*)),说实话也不难


我们容易想到这样一个 dp,\(f_i\) 为前 \(i\) 种颜色的合法方案数。把从 \(i - 1\) 转移到 \(i\) 就是把 \(s_i\) 个球球插入到缝隙里面。

但是这样不能转移,炒个例子,\(i\) 从 \(3\) 转移到 \(4\),\(i = 3\) 可能是 1 1 2 3,\(i = 4\) 就是在里面添加一个 4 在前两个 1 里面,变成 1 4 1 2 3,这是合法的。

这也给我们启发,当我们添加球的时候,可能会抵消掉前面一些不合法的空隙(不合法的空隙就是两边颜色相同的空隙)。

因此我们可以也把不合法的空隙也加入状态中,\(f_{i, j}\) 为前 \(i\) 种颜色有 \(j\) 个不合法空隙。


然后我们就可以考虑转移了。

受到上面的启发,我们会发现加入球球的时候我们会新增一些非法空隙,也会抵消原来的一些非法空隙。

因此我们设新增了 \(new\) 个非法空隙,抵消了 \(del\) 个非法空隙。我们的转移就是从 \(f_{i - 1,j}\) 到 \(f_{i, j - del+new}\)。

容易发现“新增”和“抵消”是两个基本独立的问题,因此我们考虑对着两个问题分别计数,然后乘起来。

先考虑在 \(s_i\) 个球球里新增了 \(new\) 个非法空隙。炒个例子,\(i = 7, s_i = 7, new = 3\),则一种方案是 7|7|7 7|7 7 7| 代表非法空隙。我们不难发现这个就是把 \(s_i\) 个球球划分成 \((s_i - new)\) 个块,插班可得方案数为 \(C_{s_i - 1}^{s_i - new - 1}\)。

再考虑抵消 \(del\) 个,我们令 \(s_i\) 的前缀和数组为 \(tot_i\),即前 \(i\) 种颜色一共有多少个。首先我们要找 \(del\) 个原来就有的非法空隙占掉,方案数 \(C_{j}^{del}\)。然后还有 \((new - del)\) 个,能够插在合法的 \(tot_{i - 1} - j + 1\) 个空中(因为这里的空是开头的前面和最后的后面都能插入,所以是 \(tot_{i - 1} - j + 1\) 个空位),所以是 \(C_{new - del}^{tot_{i - 1} - j + 1}\)。

因此就有这样的转移 \(f_{i, j + new - del} += f_{i - 1, j}\times C_{s_i - 1}^{s_i - new - 1} \times C_{j}^{del}\times C_{new - del}^{tot_{i - 1} - j + 1}\)

细节略多,然后我自个打的时候反复身败名裂,感谢 zyf 巨佬的调代码的帮助 qwq

//SIXIANG
#include <iostream>
#include <cmath>
#define MAXN 300
#define LL long long
#define QWQ cout << "QWQ" << endl;
using namespace std;
const LL Mod = 1e9 + 7;
LL c[310][310], f[310][310], frac[310];
bool judge(LL x) {
LL l = 1, r = x, mid;
while(l <= r) {
mid = (l + r) >> 1;
LL sqr = mid * mid;
if(sqr == x) return 1;
if(sqr > x) r = mid - 1;
else l = mid + 1;
}
return 0;
}
int a[MAXN + 10], cl[MAXN + 10], cnt = 0;
LL s[MAXN + 10], tot[MAXN + 10];
LL C(int n, int m) {
if(n < m) return 0;
else return c[n][m];
}
int main() {
c[0][0] = 1, c[1][0] = c[1][1] = 1;
frac[0] = 1;
for(int p = 2; p <= 300; p++) {
c[p][0] = 1;
for(int i = 1; i <= p; i++)
c[p][i] = (c[p - 1][i - 1] + c[p - 1][i]) % Mod;
}
for(int p = 1; p <= 300; p++)
frac[p] = frac[p - 1] * p % Mod; int n; cin >> n;
for(int p = 1; p <= n; p++)
cin >> a[p];
for(int p = 1; p <= n; p++) {
for(int i = 1; i < p; i++) {
if(judge(1ll * a[p] * a[i])) {
if(cl[i]) cl[p] = cl[i];
else cl[p] = cl[i] = ++cnt;
}
}
if(!cl[p]) cl[p] = ++cnt;
} for(int p = 1; p <= n; p++)
s[cl[p]]++;
for(int p = 1; p <= cnt; p++)
tot[p] = tot[p - 1] + s[p];
f[1][tot[1] - 1] = 1;
for(int i = 2; i <= cnt; i++)
for(int j = 0; j < tot[i - 1]; j++)
for(int ne = 0; ne < s[i]; ne++)
for(int de = 0; de + ne <= s[i]; de++) {
if(j + ne - de < 0) continue;
f[i][j + ne - de] += f[i - 1][j] * C(s[i] - 1, s[i] - ne - 1) % Mod
* C(j, de) % Mod * C(tot[i - 1] - j + 1, s[i] - ne - de) % Mod;
f[i][j + ne - de] %= Mod;
}
for(int p = 1; p <= cnt; p++)
f[cnt][0] = f[cnt][0] * 1ll * frac[s[p]] % Mod;
cout << f[cnt][0] << endl;
}

题解 P4448的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. 【Java进阶】五分钟快速掌握JVM优化概念、常用命令、工具、JUC、多线程、GC等知识

    〇.概述 (一)资料 史上最全最详细的JVM优化方案:http://www.360doc.com/content/22/0513/10/34195792_1031121509.shtml (二)内容概 ...

  2. Qwt开发笔记(二):Qwt基础框架介绍、折线图介绍、折线图Demo以及代码详解

    前言   QWT开发笔记系列整理集合,这是目前使用最为广泛的Qt图表类(Qt的QWidget代码方向只有QtCharts,Qwt,QCustomPlot),使用多年,系统性的整理,本系列旨在系统解说并 ...

  3. 用openpyxl创建工作簿和工作表

    import osimport openpyxl #设置默认路径os.chdir(r'D:/openpyxl/') #创建工作簿变量 wb = openpyxl.Workbook() #创建工作表变量 ...

  4. python基础(数据库、可视化软件Navicat、python操作MySQL)

    多表查询的两种方法 数据准备: 建表 create table dep( id int primary key auto_increment, name varchar(20) ); create t ...

  5. PTA散列表平方探测法解决冲突

    PTA散列表平方探测法解决冲突 核心问题   当所有的位置都被填上了,且不能插入关键词,要进入死循环了怎么办? 题目   本题的任务很简单:将给定的无重复正整数序列插入一个散列表,输出每个输入的数字在 ...

  6. 精华推荐 | 【深入浅出RocketMQ原理及实战】「性能原理挖掘系列」透彻剖析贯穿RocketMQ的事务性消息的底层原理并在分析其实际开发场景

    什么是事务消息 事务消息(Transactional Message)是指应用本地事务和发送消息操作可以被定义到全局事务中,要么同时成功,要么同时失败.RocketMQ的事务消息提供类似 X/Open ...

  7. 定制.NET 6.0的Middleware中间件

    大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 在本文中,我们将学习中间件,以及如何使用它进一步定制应用程序.我们将快速学习中间件 ...

  8. java中加号的用法

    注意java中+号的使用 public class Add { public static void main(String[] args) { System.out.println(100+80); ...

  9. 痞子衡嵌入式:对比恩智浦全系列MCU(包含Kinetis/LPC/i.MXRT/MCX)的GPIO电平中断设计差异

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦全系列MCU(包含Kinetis, LPC, i.MXRT, MCX)的GPIO电平中断设计差异. 在痞子衡旧文 <以i.M ...

  10. 使用腾讯云部署war包

    目录 1.前期准备 2.springboot打war包 3.部署war包 4.导入数据库 5.修改Tomcat启动端口 6.启动服务器 7.设置腾讯云服务器防火墙规则 8.从外部访问 9.总结 10. ...