On the Bench

两个数如果所有质因子的奇偶性相同则是同一个数,问题就变成了给你n个数, 相同数字不能相邻的方案数。

dp[ i ][ j ]表示前 i 种数字已经处理完, 还有 j 个位置需要隔开的方案数。

转移的话, 我们枚举第i + 1种数字分成的段数, 然后枚举有几段插到 j 个空格里面, 然后转移。

最后乘上各种数字个数的阶乘。

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-;
const double PI = acos(-); template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < ) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;} int n, cnt, a[N], c[N];
int g[N][N], sum[N];
int dp[N][N];
ull hs[N];
map<int, int> Map;
vector<ull> oo; int F[N], Finv[N], inv[N]; void init() {
inv[] = F[] = Finv[] = ;
for(int i = ; i < N; i++) inv[i] = 1LL * (mod - mod / i) * inv[mod % i] % mod;
for(int i = ; i < N; i++) F[i] = 1LL * F[i - ] * i % mod;
for(int i = ; i < N; i++) Finv[i] = 1LL * Finv[i - ] * inv[i] % mod;
}
int comb(int n, int m) {
if(n < || n < m) return ;
return 1LL * F[n] * Finv[m] % mod * Finv[n - m] % mod;
}
int main() {
init();
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
Map.clear();
for(int j = ; j * j <= a[i]; j++) {
if(a[i] % j) continue;
while(a[i] % j == ) {
Map[j]++;
a[i] /= j;
}
}
if(a[i] > ) Map[a[i]]++;
for(auto& t : Map) {
if(t.se & ) {
hs[i] *= ;
hs[i] += t.fi;
}
}
oo.push_back(hs[i]);
}
sort(ALL(oo));
oo.erase(unique(ALL(oo)), oo.end());
for(int i = ; i <= n; i++) a[i] = lower_bound(ALL(oo), hs[i]) - oo.begin() + ;
for(int i = ; i <= n; i++) c[a[i]]++;
cnt = n;
n = SZ(oo);
for(int i = ; i <= n; i++) sum[i] = sum[i - ] + c[i];
g[][] = ;
for(int i = ; i <= cnt; i++) {
for(int j = ; j <= cnt; j++) {
if(!g[i][j]) continue;
for(int k = ; i + k <= cnt; k++) {
add(g[i + k][j + ], g[i][j]);
}
}
}
dp[][c[] - ] = ;
for(int i = ; i < n; i++) {
for(int j = ; j <= cnt; j++) {
if(!dp[i][j]) continue;
int num = c[i + ];
for(int k = ; k <= num && k <= sum[i] + ; k++) {
int way = g[num][k];
for(int z = max(, k - sum[i] - + j); z <= k; z++) {
add(dp[i + ][j - z + num - k], 1LL * way * comb(j, z) % mod * comb(sum[i] + - j, k - z) % mod * dp[i][j] % mod);
}
}
}
}
int ans = dp[n][];
for(int i = ; i <= n; i++)
ans = 1LL * ans * F[c[i]] % mod;
printf("%d\n", ans);
return ;
} /*
*/

Codeforces 840C On the Bench dp的更多相关文章

  1. CodeForces 840C - On the Bench | Codeforces Round #429 (Div. 1)

    思路来自FXXL中的某个链接 /* CodeForces 840C - On the Bench [ DP ] | Codeforces Round #429 (Div. 1) 题意: 给出一个数组, ...

  2. Codeforces 840C - On the Bench(dp/容斥原理)

    Codeforces 题目传送门 & 洛谷题目传送门 这是一道 *2500 的 D1C,可个人认为难度堪比某些 *2700 *2800. 不过嘛,*2500 终究还是 *2500,还是被我自己 ...

  3. codeforces 429 On the Bench dp+排列组合 限制相邻元素,求合法序列数。

    限制相邻元素,求合法序列数. /** 题目:On the Bench 链接:http://codeforces.com/problemset/problem/840/C 题意:求相邻的元素相乘不为平方 ...

  4. Codeforces 840C. On the Bench 动态规划 排列组合

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF840C.html 题解 首先,我们可以发现,如果把每一个数的平方因子都除掉,那么剩下的数,不相等的数都可以相 ...

  5. [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)

    [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...

  6. Codeforces 840C 题解(DP+组合数学)

    题面 传送门:http://codeforces.com/problemset/problem/840/C C. On the Bench time limit per test2 seconds m ...

  7. codeforces 721C (拓排 + DP)

    题目链接:http://codeforces.com/contest/721/problem/C 题意:从1走到n,问在时间T内最多经过多少个点,按路径顺序输出. 思路:比赛的时候只想到拓排然后就不知 ...

  8. codeforces 711C Coloring Trees(DP)

    题目链接:http://codeforces.com/problemset/problem/711/C O(n^4)的复杂度,以为会超时的 思路:dp[i][j][k]表示第i棵数用颜色k涂完后bea ...

  9. codeforces 55D - Beautiful numbers(数位DP+离散化)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

随机推荐

  1. Bugku 杂项 眼见非实

    把文件放进Kali中可以看到这是一个zip文件,解压后得到一个docx,继续翻 (在windows中是打不开的 在word/document.xml中可以找到flag

  2. JarvisOJ Misc webshell分析

    分析压缩包中的数据包文件并获取flag.flag为32位大写md5. 神仙们还是强啊,webshell主要看http流,再过滤只剩下post请求 可以使用 http.request.method == ...

  3. [十二省联考2019]异或粽子——可持久化trie树+堆

    题目链接: [十二省联考2019]异或粽子 求前$k$大异或区间,可以发现$k$比较小,我们考虑找出每个区间. 为了快速得到一个区间的异或和,将原序列做前缀异或和. 对于每个点作为右端点时,我们维护出 ...

  4. [问题]Android listView item edittext 不能调用软键盘输入法

    android listview item edittext not  softkeyboard edittext可以获取焦点, 可以触发事件, 但是就是不能调用输入法, 不知道为什么? 难道不能在i ...

  5. docker-跨主机存储

    容器分类 从业务数据的角度看,容器可以分为两类:无状态(stateless)容器和有状态(stateful)容器. 无状态是指容器在运行过程中不需要保存数据,每次访问的结果不依赖上一次访问,比如提供静 ...

  6. request对象的方法及其参数的传递

    先设计一个简单的登录界面index.htm: <html><head><title>request的使用</title></head>< ...

  7. java.lang.OutOfMemoryError: Java heap space内存不足问题

    今晚,在定义一个new int[19001][13001]的数组时候内存不够:特转了一下方法: Exception in thread "main" java.lang.OutOf ...

  8. 第六节:反射(几种写法、好处和弊端、利用反射实现IOC)

    一. 加载dll,读取相关信息 1. 加载程序集的三种方式 调用Assembly类下的三个方法:Load.LoadFile.LoadFrom. //1.1 Load方法:动态默认加载当前路径下的(bi ...

  9. spring和mybatis的整合开发(基于MapperFactoryBean的整合开发(方便简单不复杂))

    MapperFactoryBean是mybati-spring团队提供的一个用于根据mapper接口生成mapper对象的类. 在spring配置文件中可以配置以下参数: 1.mapperInterf ...

  10. Python3.6及以上pip安装pymssql错误的解决办法[Windows&Linux freetds安装]

    只有由于Python3.6装不上 pymssql,所以一直用Python3.5的版本. 报错界面 现在有了新的解决方法: 原帖如下: https://docs.microsoft.com/en-us/ ...