Codeforces Round #429 (Div. 2) E. On the Bench
2 seconds
256 megabytes
standard input
standard output
A year ago on the bench in public park Leha found an array of n numbers. Leha believes that permutation p is right if for all 1 ≤ i < n condition, that api·api + 1 is not perfect square, holds. Leha wants to find number of right permutations modulo 109 + 7.
First line of input data contains single integer n (1 ≤ n ≤ 300) — length of the array.
Next line contains n integers a1, a2, ... , an (1 ≤ ai ≤ 109) — found array.
Output single integer — number of right permutations modulo 109 + 7.
3
1 2 4
2
7
5 2 4 2 4 1 1
144
For first example:
[1, 2, 4] — right permutation, because 2 and 8 are not perfect squares.
[1, 4, 2] — wrong permutation, because 4 is square of 2.
[2, 1, 4] — wrong permutation, because 4 is square of 2.
[2, 4, 1] — wrong permutation, because 4 is square of 2.
[4, 1, 2] — wrong permutation, because 4 is square of 2.
[4, 2, 1] — right permutation, because 8 and 2 are not perfect squares.
题意 :求相邻的元素相乘不为平方数的方案数(a[0]=a[1]=1, 视 a[0] 与 a[1] 不同)
思路 :
每个数可以表示为 p1^a1 * p2^a2 * .....
如果 两个数A,B相乘为平方数 则 a1%2 = a1' %2 , a2%2 = a2'%2 .....
即 对应质因子的幂次 奇偶性相同 这样就可以划分出T组
然后题目就转化为 T种物品 相同种类物品不能放在相邻 求方案数
这题就变成原题 :https://csacademy.com/contest/archive/task/distinct_neighbours/statement/
http://acm.hdu.edu.cn/showproblem.php?pid=6116
做法为dp
dp [ i ] [ j ] 表示 插入第 i 组的物品 出现了 左右为相同物品的空隙个数为 j 的方案数
那 dp [ T ] [ 0 ] 就是最终答案了
附: cs官方题解 (原题的题解)
First we group all the distinct values in the array. Then we can solve the problem using dynamic programming:
Let dp[i][j] = the number of distinct arrays that can be obtained using the elements of the first i groups such that there are exactly j pairs of consecutive positions having the same value. The answer can be found in dp[distinctValues][0].
Now let's say the sum of frequences of the first i values is X. This means the arrrays we can build using the elements from these i groups have size X, so we can insert the elments of group i + 1 in X + 1 gaps: before the first element, after the last, and between any two consecutive. We can fix the number k of gaps where we want to insert at least one element from group i + 1, but we also need to fix the number l of these k gaps which will be between elements that previously had the same value. State dp[i][j] will update the state dp[i + 1][j - l + frequence[i + 1] - k].
The number of ways of choosing k gaps such that exactly l are between consecutive elements having the same value can be computed easily using combination formulas. We are left with finding out the number of ways of inserting frequence[i + 1] elements in k gaps. This is also a classical problem with a simple answer: Comb(frequence[i + 1] - 1, k - 1).
具体转移方程见代码 :
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <functional> #define mp make_pair
#define pb push_back
#define mes(a,b) memset(a,b,sizeof(a))
#define mes0(a) memset(a,0,sizeof(a))
#define lson l,mid,pos<<1
#define rson mid+1,r,pos<<1|1
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define fi first
#define se second
#define sss(a) a::iterator
#define all(a) a.begin(),a.end() using namespace std; typedef double DB;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<long long ,int> pli;
typedef pair<int,long long > pil;
typedef pair<string,int> psi;
typedef pair<long long ,long long > pll; const int inf = 0x3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int maxn = +;
const int mod = 1e9+;
LL dp[][];
LL C[][];
LL fact[];
int cnt[];
int a[];
int vis[];
int sz;
int check(LL x)
{
LL l=,r=1e9;
LL now=l;
while (l<=r){
LL mid=(l+r)>>;
if (mid*mid<=x)now=mid,l=mid+;
else r=mid-;
}
return now*now==x;
}
inline LL M(LL x)
{
return x%mod;
}
void init()
{
C[][]=;
fact[]=;
for (int i=;i<=;i++){
C[i][]=;
for (int j=;j<=i;j++){
C[i][j]=M(C[i-][j]+C[i-][j-]);
}
}
for (int i=;i<=;i++)fact[i]=M(fact[i-]*i);
}
void slove()
{
dp[][cnt[]-]=;
int lim=cnt[];
for (int i=;i<sz;i++){
for (int j=;j<lim;j++){ /// dp[i-1][j]
for (int k=;k<cnt[i];k++){/// group[i]分成k+1组 ,cnt[i]-1-k个空隙
for (int m=;m<=min(j,k+);m++){ /// 选了m个左右相同的空隙插入
dp[i][j+cnt[i]--k-m]=M(dp[i][j+cnt[i]--k-m]+dp[i-][j]*C[cnt[i]-][k]%mod*C[j][m]%mod*C[lim--j+][k+-m]);
}
}
}
lim+=cnt[i];
}
LL ans=dp[sz-][];
for (int i=;i<sz;i++){
ans*=fact[cnt[i]];
ans%=mod;
}
cout<<ans<<endl;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
scanf("%d",&n);
for (int i=;i<n;i++){
scanf("%d",a+i);
}
for (int i=;i<n;i++){
if (vis[i]==){
for (int j=i;j<n;j++){
if (check(1LL*a[i]*a[j])){
cnt[sz]++;
vis[j]=;
}
}
sz++;
}
}
init();
slove();
return ;
}
Codeforces Round #429 (Div. 2) E. On the Bench的更多相关文章
- Codeforces Round #429 (Div. 1) C. On the Bench(dp + 组合数)
题意 一个长度为 \(n\) 的序列 \(A\) ,定义一个 \(1\) 到 \(n\) 的排列 \(p\) 是合法的,当且仅当 \(\forall i \in [1, n − 1], A_{p_i} ...
- 【做题】Codeforces Round #429 (Div. 2) E. On the Bench——组合问题+dp
题目大意是给你n个数,求相邻两数相乘不是完全平方数的排列数. 一开始看到这题的时候,本人便想给相乘为完全平方数的数对建边,然后就写萎了... 后来通过集体智慧发现这个重要性质:对于自然数a,b,c,若 ...
- CodeForces 840C - On the Bench | Codeforces Round #429 (Div. 1)
思路来自FXXL中的某个链接 /* CodeForces 840C - On the Bench [ DP ] | Codeforces Round #429 (Div. 1) 题意: 给出一个数组, ...
- CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)
思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上 ...
- CodeForces 840A - Leha and Function | Codeforces Round #429 (Div. 1)
/* CodeForces 840A - Leha and Function [ 贪心 ] | Codeforces Round #429 (Div. 1) A越大,B越小,越好 */ #includ ...
- 【Codeforces Round #429 (Div. 2) A】Generous Kefa
[Link]:http://codeforces.com/contest/841/problem/A [Description] [Solution] 模拟,贪心,每个朋友尽量地多给气球. [Numb ...
- Codeforces Round #429 (Div. 2/Div. 1) [ A/_. Generous Kefa ] [ B/_. Godsend ] [ C/A. Leha and Function ] [ D/B. Leha and another game about graph ] [ E/C. On the Bench ] [ _/D. Destiny ]
PROBLEM A/_ - Generous Kefa 题 OvO http://codeforces.com/contest/841/problem/A cf 841a 解 只要不存在某个字母,它的 ...
- 【Codeforces Round #429 (Div. 2) C】Leha and Function
[Link]:http://codeforces.com/contest/841/problem/C [Description] [Solution] 看到最大的和最小的对应,第二大的和第二小的对应. ...
- 【Codeforces Round #429 (Div. 2) B】 Godsend
[Link]:http://codeforces.com/contest/841/problem/B [Description] 两个人轮流对一个数组玩游戏,第一个人可以把连续的一段为奇数的拿走,第二 ...
随机推荐
- socket网络编程基础小记
"一切皆Socket!" 话虽些许夸张.可是事实也是,如今的网络编程差点儿都是用的socket. --有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间怎样通 ...
- AWK 怎么读取标准输入(STDIN)
在 awk 系列中,我们将会看到几个例子,你可以筛选其他命令的输出代替从一个文件读取输入作为 awk 的输入.我们首先从使用 dir 命令开始,它类似于 ls 命令. 在第一个例子下面,我们使用 di ...
- 【笔记】探索js 的this 对象 (第三部分)
了解完函数的调用区域是如何影响this 对象的,还有this 的各种绑定方式以及各种绑定方式的优先级后 最后一部分,来了解一下this 的一些例外情况 1.被忽略的this 例如在使用bind 方法时 ...
- 在Linux命令行下查询当前所使用的shell版本与种类的方法
原文: https://www.jb51.net/LINUXjishu/407463.html ---------------------------------------------------- ...
- JSP中的TAG文件和TLD文件小结
在jsp文件中,可以引用tag和tld文件. 1.对于tag文件 <%@ taglib prefix="ui" tagdir="/WEB-INF/tags" ...
- 解决启动WebLogic输入用户名密码问题
转自:http://wenku.baidu.com/link?url=M6wJDVwm_Us6NsYi5u-PDTTbTHpO_ncsv5yClXSxhDIhA70IRga5ZdvotT4bW__MG ...
- 解决rails4.0中send_file文件下载两次的问题
之前在开发文件下载的功能时,我遇到了一个很奇怪的问题,点击下载链接,在chrome console中会出现两次请求,第一次返回200,下载的数据缓存在chrome的cache中,第二次返回304,直接 ...
- M.U.G.E.N Error怎么办
当运行乱舞格斗2008的时候出现以下错误. 在任务管理器中找到M.U.G.E.N.exe这个进程,右击设置相关性,然后取消勾选其中一个,点击确定. 不要关闭这个窗口,否则M.U.G.E.N这个进程也将 ...
- LoadRunner访问 Mysql数据库
这是很久以前编写的一个测试案例,那时是为了检查大量往Mysql数据库里插入数据,看一下数据库的性能如何?服务器是否会很快就被写满了. 前期的准备工作:Mysql 数据库搭建,LoadRunner,li ...
- taro 自定义 轮播图组件
1.代码 components/MySwiper/index.js /** * 轮播图组件 */ import Taro, { Component } from '@tarojs/taro'; imp ...