题解 P4448
如果这不是一道原题,这道题出的还不错,是个比较毒瘤的数数。由于我太菜了反正我自己没有做出来后面的 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的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- 关于cannot remove ‘directory': Directory not empty的解决办法
解决方法 首先你应该使用 rm -rf 目录名 这样确保可以递归删除目录 如果出现 cannot remove 'directory': Directory not empty 报错信息,重启电脑解决 ...
- ArcEngine要素编辑遇到的一些问题
1.如何开启编辑 IMap myMap = this._Aplication.ActiveView.FocusMap; IWorkspace myWorkspace = (myMap25Sheet.P ...
- 【大数据面试】sqoop:空值、数据一致性、列式存储导出、数据量、数据倾斜
一.有没有遇到过问题,怎么进行解决的 1.空值问题 本质:hive底层存储空数据使用\n<==>MySQL存储空数据使用null 解决:双向导入均分别使用两个参数☆,之前讲过 2.数据一致 ...
- ArcObjects SDK 012 PageLayout和Page
1.从ArcMap角度看结构 一个Mxd文件包含一个PageLayout对象和一个多多个Map对象,每个Map会被包成MapFrame,添加到PageLayout中.我们用ArcMap打开一个mxd文 ...
- ORM常用字段与参数(自定义字段)
目录 一:orm中常用字段及参数 1.说明 2.自定义字段使用 3.ORM字段参数 一:orm中常用字段及参数 1.说明 id字段是自动添加的,如果你想要指定自定义主键,只需在其中一个字段中指定pri ...
- 用 while 生成猜数字
import java.util.Random; import java.util.Scanner; public class zy2 { public static void main(String ...
- kali之pip和pip3安装
安装pip 首先安装setuptools,setuptools是 Python Enterprise Application Kit(PEAK)的一个副项目,它 是一组Python的 distutil ...
- drf快速使用 CBV源码分析 drf之APIView分析 drf之Request对象分析
目录 序列化和反序列化 drf介绍和安装 使用原生django写接口 django DRF安装 drf快速使用 模型 序列化类 视图 路由 datagrip 使用postman测试接口 CBV源码分析 ...
- ffmpeg第8篇:使用ffprobe采集文件信息
1. 前言 ffprobe是ffmpeg的其中一个模块,主要用于查看文件信息,咱们知道一个MP4文件其实不仅仅包含了音视频数据,还有如元数据等其它信息,但是实际上咱们关心的往往是音视频数据部分,今天来 ...
- [深度学习]Keras利用VGG进行迁移学习模板
# -*- coding: UTF-8 -*- import keras from keras import Model from keras.applications import VGG16 fr ...