When the analog cut off, I feel this question is very good. (Although T1 will not expect what took a twenty-five points messing around, T2 finally staged a string of dp, also opened last array of small ...... but finally the dog into the top five)
Questions face Description:
Construction of a N points directed graph G, no initial edge. Next construct a side length E sequence A, a sequence each edge are satisfied 1≤s, t≤N and s ≠ t directed edge (s, t), and the sequence of the sides different from each other . These edges in order to be added to G, each counting the number of strongly connected components of the current graph and recorded after the addition to obtain a new sequence of positive integers length E of B. If the sequence of the two sides of the same B obtained they are essentially the same as claimed.
Will the different nature of the sequence of how many sides there are, as long as you find the answer to 10 ^ 9 + 7 result of modulo.
Obviously can not run over and over again Tarjan (laughing cry)
We first analyze the problem:
First, we consider a legitimate sequence B, must be no increase in monotonous. We will consider a chain as a backbone graph, we added for each edge, we consider it is to continue to expand this chain, or even the casual side in the original chain on. So we designed a state of the conventional F [i] [j] denotes the front edges i, j number of programs are now strongly connected components.
So it is clear that for some i and j is a relationship, not any pair i, j are legitimate.
So we consider the wave:
Suppose now that the sequence is divided into k sections B, equal to the size of each segment (with some waste side), then as applied on the basis of the side chain with at least k-1 item, then that edge up to the chain there i - k +1 bar.
Setting Bi = j, j that is to say there are a strongly connected component, then the side chain apparently used a minimum of n - j Article (a ring, j - 1 outlier, n - j + 1 point on the ring , n - j + 1 the rings of the top, which has a reverse side).
We should then obviously satisfy n - j <= i - k + 1, and more, that is to say for a pair i, j we must satisfy i + j> = n + k -1 job.
This is the case whether lawfully received limit k. That is for a pair i, j, the corresponding situations are not legitimate, lawful situation i, j is a subset of all of its conditions.
Then we will add a dimensional limit, F [i] [j] [k] i applied to the representative sides, has a strongly connected component j, k is divided into several program sections.
Then we found that, since this is a simple graph, when the number of the strongly connected component is j, the number of edges is capped, at most (n - j + 1) * (n - 1) + (j - 1) * (j - 2) / 2.
We must satisfy the condition i <= (n - j + 1) * (n - 1) + (j - 1) * (j - 2) / 2.
Then f [i] [j] [k] of the transfer is very good, as long as consideration is whether the i th edge scrap to: f [i] [j] [k] + = f [i - 1] [h ] [k - 1] + f [i - 1] [j] [k].
By maintaining the prefix and as we put down to the complexity of the n- 3 , but obviously we still are not satisfied> /// <
We observed that i + j> = n + k -1, found that i> = 2n when the always true, so we do not need the dimension of k, f [i] [j] will be able to transfer also same.
That's it it! Of course, since the simulation time n is 100, then there is no need to transfer the two-dimensional, three-dimensional n . 4 is acceptable.
Code:
1. simulation code:
#include <iostream> #include <cstdio> #define maxn 102 #define mod 1000000007 using namespace std; int dp[maxn * maxn][maxn][maxn]; int add(int x, int y) { x += y; return x >= mod ? x - mod : x; } int main() { int n; cin >> n; for (int i = n; i >= 0; -- i) dp[0][i][0] = 1; for (int e = 1; e <= n * (n - 1); ++ e) { int ans = 0; for (int v = 1; v <= n; ++ v) for (int m = 0; m < n; ++ m) if (e >= (n - v) + m && e <= (n - v + 1) * (n - 1) + (v - 1) * (v - 2) / 2) { dp[e][v][m] = add(dp[e][v][m], (mod + dp[e - 1][v][m] - dp[e - 1][v + 1][m]) % mod); dp[e][v][m] = add(dp[e][v][m], dp[e - 1][v + 1][m - 1]); ans = add(ans, dp[e][v][m]); } for (int m = 0; m <= n; ++ m) for (int v = n - 1; v >= 0; -- v) dp[e][v][m] = add(dp[e][v][m], dp[e][v + 1][m]); printf("%d ",ans); } return 0; }
2. n <= 400 dimensional optimized code:
#include<cstdio> #include<iostream> #include<queue> #include<algorithm> #include<cmath> #include<vector> #include<cstring> using namespace std; #define mod 1000000007 const int maxn = 500; int lim[maxn], f[2][maxn][maxn], sf[2][maxn][maxn], g[2][maxn], sg[2][maxn],ans[maxn*maxn]; int n; int main() { scanf("%d",&n); for (int i = 1; i <= n; i++) lim[i] = (n - i + 1) * (n - 1) + (i - 1) * (i - 2) / 2; f[1][n][1] = ans[1] = 1; for (int i = 1; i <= n; i++) sf[1][i][1] = 1; for (int i = 2; i <= min(n * (n - 1), n << 1); i++) { int op = i & 1; for (int j = 1; j <= n; j++) for (int k = 1; k <= n; k++) f[op][j][k] = 0; for (int j=1; j<=n; j++) if (i<=lim[j]) for (int k = 1; k <= n; k++) If (i + j> = n + k - 1 ) f [on] [j] [k] = (f [at ^ 1 ] [j] [k] + sf [at ^ 1 ] [j + 1 ] [k - 1 ])% mod; for ( int j = n; j> = 1 ; j-- ) for ( int k = 1 ; k <= n; k ++ ) { sf [on] [j] [k] = (sf [on] [j + 1 ] [k] + f [on] [j] [k])% mod; ans [i] = (ans [i] + f [on] [j] [k])% mod; } } for (int j = 1; j <= n; j++) for (int k = 1; k <= n; k++) g[0][j] = (g[0][j] + f[0][j][k]) % mod; for (int j = n; j >= 1; j--) sg[0][j] = (sg[0][j + 1] + g[0][j]) % mod; for (int i = (n << 1) + 1; i <= n * (n - 1); i++) { int op = i & 1; for (int j = 1; j <= n; j++) g[op][j] = 0; for (int j = 1; j <= n; j++) if (i <= lim[j]) g[op][j] = sg[op ^ 1][j]; for (int j = n; j >= 1; j--) { sg[op][j] = (sg[op][j + 1] + g[op][j]) % mod; ans[i] = (ans[i] + g[op][j]) % mod; } } for (int i = 1; i <= n * (n - 1); i++) printf("%d ", ans[i]); printf("\n"); return 0; }