time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

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.

Input

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

Output single integer — number of right permutations modulo 109 + 7.

Examples
Input
3
1 2 4
Output
2
Input
7
5 2 4 2 4 1 1
Output
144
Note

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的更多相关文章

  1. Codeforces Round #429 (Div. 1) C. On the Bench(dp + 组合数)

    题意 一个长度为 \(n\) 的序列 \(A\) ,定义一个 \(1\) 到 \(n\) 的排列 \(p\) 是合法的,当且仅当 \(\forall i \in [1, n − 1], A_{p_i} ...

  2. 【做题】Codeforces Round #429 (Div. 2) E. On the Bench——组合问题+dp

    题目大意是给你n个数,求相邻两数相乘不是完全平方数的排列数. 一开始看到这题的时候,本人便想给相乘为完全平方数的数对建边,然后就写萎了... 后来通过集体智慧发现这个重要性质:对于自然数a,b,c,若 ...

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

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

  4. CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)

    思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上 ...

  5. CodeForces 840A - Leha and Function | Codeforces Round #429 (Div. 1)

    /* CodeForces 840A - Leha and Function [ 贪心 ] | Codeforces Round #429 (Div. 1) A越大,B越小,越好 */ #includ ...

  6. 【Codeforces Round #429 (Div. 2) A】Generous Kefa

    [Link]:http://codeforces.com/contest/841/problem/A [Description] [Solution] 模拟,贪心,每个朋友尽量地多给气球. [Numb ...

  7. 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 解 只要不存在某个字母,它的 ...

  8. 【Codeforces Round #429 (Div. 2) C】Leha and Function

    [Link]:http://codeforces.com/contest/841/problem/C [Description] [Solution] 看到最大的和最小的对应,第二大的和第二小的对应. ...

  9. 【Codeforces Round #429 (Div. 2) B】 Godsend

    [Link]:http://codeforces.com/contest/841/problem/B [Description] 两个人轮流对一个数组玩游戏,第一个人可以把连续的一段为奇数的拿走,第二 ...

随机推荐

  1. [CF 276C]Little Girl and Maximum Sum[差分数列]

    题意: 给出n项的数列A[ ], q个询问, 询问 [ l, r ] 之间项的和. 求A的全排列中该和的最大值. 思路: 记录所有询问, 利用差分数列qd[ ], 标记第 i 项被询问的次数( 每次区 ...

  2. vc6下unicode支持

    最近在研究一个串口程序,要启用unicode支持,发现还挺麻烦的. VC6.0设定UNICODE编译环境 VC++ 6.0支持Unicode编程,但默认的是ANSI,所以开发人员只需要稍微改变一下编写 ...

  3. 手机端UC浏览器,在java开发的下载功能中存在的问题?

    在java web开发中,不同浏览器对下载文件的格式有不同的要求,有时会出现视频,音频等文件无法下载的问题.我在开发中,也遇到类似的问题,觉得很苦恼. 经过百度和请教学习,得到2个解决方案. 首先得到 ...

  4. vue - .postcssrc.js

    描述:添加浏览器私缀(私缀是上世纪90年代浏览器大战的产物,也是现在新型浏览器支持某些新API,而其它浏览器不支持的证明!) 我们看看App.vue 再来看看打包后的css文件 一切都是靠你postc ...

  5. 算法笔记_093:蓝桥杯练习 Problem S4: Interesting Numbers 加强版(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 Problem Description We call a number interesting, if and only if: 1. Its d ...

  6. 在LoadRunner中查找和替换字符串

    参考<Search & Replace function for LoadRunner>: http://ptfrontline.wordpress.com/2009/03/13/ ...

  7. git push --set-upstream origin

    设置本地分支追踪远程分支 之后就可以直接使用git push提交代码

  8. ZK框架笔记5、事件

            事件是org.zkoss.zk.ui.event.Event类,它通知应用程序发生了什么事情.每一种类型的事件都由一个特定的类来表示.         要响应一个事件,应用程序必须为事 ...

  9. 使用js+Ajax请求API接口数据-带请求头方式

    C# http请求带请求头部分 先上代码: <script type="text/javascript"> function zLoginCheck() { var A ...

  10. Unity 背包道具搜索(2)

    上一篇: http://www.cnblogs.com/plateFace/p/6490577.html 上次编写代码只是把逻辑编写出来, 对于里面的代码还存在一下问题 1. 搜索功能没有解耦 2. ...