1. 程式人生 > >Codeforces 840C On the Bench

Codeforces 840C On the Bench

題目傳送門

  傳送門I

  傳送門II

題目大意

  給定$n$個數,我們認為它們互不相同,即使它們數值上相等,問存在多少排列方式,使得任意兩個相鄰位置上的數的乘積不是完全平方數。

  顯然一個正整數$x$可以被表示為$d_{1}\cdot s_{1}^{2}$,其中$d,s\in N_{+}$,$d$取最小值。

  另一個正整數$y$表示為$d_{2}\cdot s_{2}^{2}$。那麼$xy$是完全平方數的充分必要條件是$d_{1} = d_{2}$。(可以先證明$d$不含平方因子,然後用反證法證明)

  然後問題可以轉化成有$n$個互不相同的球,每個球被塗有一種顏色,要求將所有球排成一排,同種顏色的球不相鄰的方案數。

  考慮設$f_{i, j}$表示當前考慮到第$i$種顏色,已經有$j$個連續的段。

  每次考慮放入一種顏色的所有球。主要有三種情況:

  1. 一個球被拿去連線兩段球
  2. 一個球被放入了一個獨立的段
  3. 一個球放在某一段的端點處

  我們列舉第一種情況的球的個數。假設第$i$種顏色有$c$個球,原本有$j$段球,現在我要拿$x$球作為第一種情況,拿$y$個球作為第二種情況。(這樣根據之前有多少段計算現在有多少段)

  1. 對於第一部分,首先我需要選擇$x$個球,然後在$j - 1$個間隙中選出$x$個間隙,再決定每個球放在哪個間隙。這一部分方案數是$\binom{c}{x}\binom{j - 1}{x}x!$
  2. 對於第二部分,我需要從剩下的$x - c$個球中選出$y$個球,我先將它排列好,然後分成$j - x$段插入間隙中(這個插入和上面的那種情況不同,這裡不會連線兩端點)。顯然這一部分的方案數是$\binom{c - x}{y}\binom{y + j - x}{j - x}y!$
  3. 對於第三部分,剩下的球已經是確定的了,不用考慮。我只需要從$2(j - x)$個可選的位置中選擇$c - x - y$個位置,然後排列一下把球放上去。

  時間複雜度$O(n^{3})$

Code

  1 /**
  2  * Codeforces
  3  * Problem#840C
  4  * Accepted
5 * Time: 62ms 6 * Memory: 1800k 7 */ 8 #include <algorithm> 9 #include <iostream> 10 #include <cstdlib> 11 #include <cstdio> 12 using namespace std; 13 typedef bool boolean; 14 15 const int N = 305, M = 1e9 + 7; 16 17 int add(int a, int b) { 18 return ((a += b) >= M) ? (a - M) : (a); 19 } 20 21 int mul(int a, int b) { 22 return (a * 1ll * b) % M; 23 } 24 25 void exgcd(int a, int b, int& x, int& y) { 26 if (!b) 27 x = 1, y = 0; 28 else { 29 exgcd(b, a % b, y, x); 30 y -= (a / b) * x; 31 } 32 } 33 34 int inv(int a, int n) { 35 int x, y; 36 exgcd(a, n, x, y); 37 return (x < 0) ? (x + n) : (x); 38 } 39 40 int n; 41 int ar[N]; 42 int f[N][N]; 43 int fac[N], _fac[N]; 44 int C[N << 1][N << 1]; 45 46 inline void init() { 47 scanf("%d", &n); 48 for (int i = 1, x, y; i <= n; i++) { 49 scanf("%d", &x), y = 1; 50 for (int p = 2, a = 0; p * p <= x; p++, a = 0) { 51 while (!(x % p)) 52 x /= p, a ^= 1; 53 if (a) 54 y *= p; 55 } 56 if (x > 1) 57 y *= x; 58 ar[i] = y; 59 } 60 } 61 62 inline void solve() { 63 sort(ar + 1, ar + n + 1); 64 C[0][0] = 1; 65 for (int i = 1; i <= (n << 1); i++) { 66 C[i][0] = C[i][i] = 1; 67 for (int j = 1; j < i; j++) 68 C[i][j] = add(C[i - 1][j - 1], C[i - 1][j]); 69 } 70 71 fac[0] = 1; 72 for (int i = 1; i <= n; i++) 73 fac[i] = mul(fac[i - 1], i); 74 _fac[n] = inv(fac[n], M); 75 for (int i = n; i; i--) 76 _fac[i - 1] = mul(_fac[i], i); 77 78 int t = 1; 79 f[0][0] = 1; 80 for (int i = 1, r = i; i <= n; i = r, t++) { 81 while (r <= n && ar[r] == ar[i]) 82 r++; 83 int cnt = r - i; 84 for (int j = 0; j < i; j++) { 85 for (int k = j; k <= j + cnt; k++) { 86 int c_indep = k - j, c_depen = cnt - c_indep; 87 int n_indep = mul(mul(C[cnt][c_indep], fac[c_indep]), C[c_indep + j][j]); 88 int n_depen = mul(C[j * 2][c_depen], fac[c_depen]); 89 f[t][k] = add(f[t][k], mul(f[t - 1][j], mul(n_indep, n_depen))); 90 } 91 // f[t][k] = add(f[t][k], mul(f[t - 1][j], mul(mul(fac[k], _fac[j]), mul(C[j * 2][cnt - k + j], fac[cnt - k + j])))); 92 for (int con = 1; con < j; con++) { 93 for (int k = j - con; k < r; k++) { 94 int c_indep = k - j + con, c_depen = cnt - con - c_indep; 95 if (c_depen < 0) 96 break; 97 int n_conne = mul(C[j - 1][con], mul(C[cnt][con], fac[con])); 98 int n_indep = mul(C[cnt - con][c_indep], mul(fac[c_indep], C[c_indep + j - con][j - con])); 99 int n_depen = mul(C[(j - con) * 2][c_depen], fac[c_depen]); 100 f[t][k] = add(f[t][k], mul(f[t - 1][j], mul(n_conne, mul(n_indep, n_depen)))); 101 // f[t][k] = add(f[t][k], mul(f[t - 1][j], mul(mul(C[j - 1][con], ), mul(fac[j + ind], mul(_fac[j], C[(j - con) * 2][dep]))))); 102 } 103 } 104 } 105 // for (int i = 0; i < r; i++) 106 // cerr << f[t][i] << " " ; 107 // cerr << '\n'; 108 } 109 printf("%d\n", f[t - 1][1]); 110 } 111 112 int main() { 113 init(); 114 solve(); 115 return 0; 116 }

相關推薦

Codeforces 840C On the Bench - 動態規劃 - 組合數學

題目傳送門   傳送門I   傳送門II   傳送門III 題目大意   給定$n$個數,我們認為它們互不相同,即使它們數值上相等,問存在多少排列方式,使得任意兩個相鄰位置上的數的乘積不是完全平方數。   顯然一個正整數$x$可以被表示為$d_{1}\cdot s_{1}^

Codeforces 840C On the Bench

題目傳送門   傳送門I   傳送門II 題目大意   給定$n$個數,我們認為它們互不相同,即使它們數值上相等,問存在多少排列方式,使得任意兩個相鄰位置上的數的乘積不是完全平方數。   顯然一個正整數$x$可以被表示為$d_{1}\cdot s_{1}^{2}$,其中$d,s\in

【CF840C】On the Bench-DP+組合數學

測試地址:On the Bench 題目大意: 給出一個長為 n n n的序列

C. On the Bench(dp + 組合數)

題意 一個長度為 \(n\) 的序列 \(A\) ,定義一個 \(1\) 到 \(n\) 的排列 \(p\) 是合法的,當且僅當 \(\forall i \in [1, n − 1], A_{p_i} × A_{p_i+1}\) 不是完全平方數。 求有多少合法的排列,對 \(10^9 + 7\) 取模。 \(

CodeForces-266A Stones on the Table(語法練習題)

Stones on the Table time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output There are n stones

Stones on the Table【CodeForces - 266A】

Stones on the Table問題解析 題目 There are n stones on the table in a row, each of them can be red, green or blue. Count the minimum number of s

Stones on the Table CodeForces - 266A(語法練習題)

There are n stones on the table in a row, each of them can be red, green or blue. Count the minimum number of stones to take from the table so tha

Stones on the Table CodeForces - 266A

Text Reverse Time limit 2000 ms Memory limit 262144 kB Source Codeforces Round #163 (Div. 2) Tags implementation *800 EditorialAnnouncement Tutori

CodeForces - 266A Stones on the Table【水題】

Stones on the Table time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output There are n ston

CodeForces - 266A——Stones on the Table

Stones on the Table There are n stones on the table in a row, each of them can be red, green or blue. Count the minimum number of stones to

Codeforces Round #466 (Div. 2) A. Points on the line

A. Points on the lineWe've got no test cases. A big olympiad is coming up. But the problemsetters' number one priority should be adding an

[轉]The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path

right clas rup b- row 添加按鈕 n) 1-1 自帶 完整錯誤信息: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"AS IS" AND ANY EXPRESS O

My app status is Ready for Sale but I cannot see my app on the App Store. Why? 為什麽審核通過後 appstore中搜不到我的app

one soci orm event 什麽 live pstore follow following 這是蘋果的官方解答 The following factors could prevent your app from showing up on the App St

Warning: date(): It is not safe to rely on the system's timezone settings.

bsp ron notice zone asi 警告 family one str PHP調試的時候出現了警告: It is not safe to rely on the system解決方法,其實就是時區設置不正確造成的,本文提供了3種方法來解決這個問題。 實際上,

新建 jsp異常,The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path

prop 選擇 library path per png class pro found   新項目,新建jsp頁面的時候報異常: Multiple annotations found at this line: - The superclass "java

【論文:麥克風陣列增強】Speech Enhancement Based on the General Transfer Function GSC and Postfiltering

res transient ice ges nal gen image 增強 reg 作者:桂。 時間:2017-06-06 16:10:47 鏈接:http://www.cnblogs.com/xingshansi/p/6951494.html 原文鏈接:http

出現錯誤日誌:The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path

div 錯誤日誌 a.out library logs openss product arc nec tomcat6出現錯誤日誌: 信息: The APR based Apache Tomcat Native library which allows optimal pe

eclipse更改workspace中出現The superclass "javax.servlet.http.HttpServlet" was not found on the Java----問題》》

win runtime cli 名稱 tail 一個 fig workspace found 第一步:那是因為在項目中沒有告訴它應該在哪個tomcat中運行,右擊項目名稱-----》build path--》configure path---->library--

inspect a service on the swarm

docker swarm當你在一個swarm 中部署了一個服務,你可以通過以下的命令行語句來查看集群中運行的服務的詳細信息docker service inspect --pretty <SERVICE-ID>$docker machine ssh manager1 查看helloworld 服

08_drain a node on the swarm

docker swarm 在之前的小節,所有的節點的狀態都是運行著的可用狀態。swarm manager 可以分配任務給任意可用的節點。有時候,你可能需要對某臺服務器進行維護,你需要配置某個節點為drain狀態,即排幹該節點上面的所有運行的容器。drain狀態可以防止維護節點再收到 管理節點的指令。它