First, praise the topic, good question
Test instructions
Marjar University have decided to upgrade the infrastructure of school intranet by using Fiber-optic technology. There is N buildings in the school. Each building is installed with one router. These routers is connected by optical cables in such a-path that there is exactly one paths between any and routers.
Each router should is initialized with a operating frequency before Fi it starts to work. Due to the limitations of hardware and environment, the operating frequency should is an integer number within [ Li , ]. In order to reduce the signal noise, the operating frequency of any and adjacent routers should be co-prime.
Edward is the headmaster of Marjar University. He is very interested in the number of different ways to initialize the operating frequency. Please write a program to help him! To make the report-simple and neat, you have need to calculate the sum of Fi (modulo 1000000007) in all solutions for E Ach router.
In English, it probably means that each point in a tree can give a value of l[i] ~ R[i], the value of the adjacent two points to coprime, and the value of all the cases of each point, mod 1000000007
The idea is to enumerate a point, and then enumerate the values (i) at that point, and then find out how many (Dp[i]) This is, then the answer on this point is dp[1] * 1 + dp[2] * 2 + dp[3] * 3 + ...
Then there is the tree DP, the transfer equation is dp[i][j] =π{(∑{dp[t][k] | gcd (j, k) = = 1}) | I and t adjacent}
But the complexity of this transfer is 50 * 50000 * 50000, even if the 15-second time limit expires
So we can consider to use the non-coprime to transfer;
Set S[i] = ∑dp[i][j]
Then the transfer equation is dp[i][j] =π{(s[i]- ∑{dp[t][k] | gcd (j, k)! = 1}) | I and t adjacent}
For Dp[i][j], we can decompose J mass factor, assuming j = p1^e1 * P2^e2 * p3^e3, the number within 50000 has a maximum of 6 different qualitative factors;
Then we record div[i][k] = ∑{ Dp[i][j] | J is a multiple of k}, which can be processed by Nlogn complexity;
so ∑{ dp[t][k ] | GCD (j, k)! = 1} = Div[t][p1] + div[t][p2] + div[t][p3] -div[t] [P1 * P2] -div[t][p1 * p3] -div[t][p2 * P3] + div[t][p1 * p2 * P3], this can be done with the principle of tolerance, the complexity of up to 2 ^ 6;
So the DP once complexity is probably the 50000 * (log50000 + 2^6);
If you want to count 50 points, it will still time out;
But this is a tree, for each point is DP once a lot of repetitive things, so we do not go to all DP once, for example, to calculate the I point, to calculate the J point, assuming I j adjacent, then in the DP array only the values of I and J have changed, we just have to calculate the DP transfer of these two points is enough.
For more details, see the code:
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <ctime > #include <vector>using namespace std;typedef long long ll;const int N = 50009;const LL M = 1000000007;inline voi d addit (int &a, int b) {A + = B; if (a >= m) A-= M; inline int sub (int a, int b) {a = B; if (a < 0) A + = M; if (a >= m) A-= M; return A;} struct num{int p[11]; int ALLP;} num[n];struct data{int dp[n], div[n], all;} DATA[55], Fb[55];int l[55], r[55];int ans[55];int n;vector<int> e[55];bool vis[55];int RCN, rcv;void print () {for (int i = 0; i < n; i++) {printf ("i =%d\n", i); for (int j = 0; J < 6; j + +) printf ("dp[%d] =%d\n", J, Data[i].dp[j]); }}int RC (int i, int xs) {int T, r = 0; for (; i < NUM[RCN].ALLP; i++) {if (XS * num[rcn].p[i] <= R[RCV]) t = data[rcv].div[xs * Num[rcn].p[i]; else T = 0; printf ("***%d, t =%d\n", XS * num[rcn].p[i], t); Addit (R, Sub (t, RC (i + 1, XS * num[rcn].p[i])); }//printf ("R =%d\n", r); return r;} void Dfstree (int pre, int now) {if (Vis[now]) return; Vis[now] = true; int I, siz = E[now].size (); for (i = 0; i < siz; i++) Dfstree (now, e[now][i]); if (pre >= 0 && siz <= 1) for (i = l[now]; I <= R[now]; i++) data[now].dp[i] = 1; else for (i = l[now]; I <= R[now]; i++) {data[now].dp[i] = 1; for (int j = 0; J < Siz; J + +) if (e[now][j]! = Pre) {RCN = i; RCV = E[now][j]; Data[now].dp[i] = (LL) (Data[now].dp[i]) * SUB (data[e[now][j]].all, RC (0, 1))% M; }} data[now].all = 0; for (i = 1; I <= R[now]; i++) {data[now].div[i] = 0; for (int j = i; J <= R[now]; j + = i) if (J >= L[now]) Addit (Data[now].div[i], data[now].dp[j]); if (i >= L[now]) addit (Data[now].all, data[now].dp[i]); }}void dfs (int pre, int now, int.) {Dfstree ( -1, now); if (now = = 1) print (); int I, siz = E[now].size (); Ans[now] = 0; for (i = l[now]; I <= R[now]; i++) Addit (Ans[now], (LL) data[now].dp[i] * I% M); Fb[deep] = Data[now]; Vis[now] = false; for (i = 0; i < siz; i++) if (e[now][i]! = Pre) {Vis[e[now][i]] = false; Fb[deep] = data[e[now][i]]; Vis[now] = false; DFS (now, e[now][i], deep + 1); Data[e[now][i]] = Fb[deep]; Vis[e[now][i]] = true; }}void init () {int I, j, K; for (i = 0; i < N; i++) NUM[I].ALLP = 0; for (i = 2; i < N, i++) if (NUM[I].ALLP = = 0) for (j = i; J < N; J + = i) num[j].p[num[j].allp++] = i;} int main () {//freopen ("13f.in", "R", stdin); Init (); int T; scanf ("%d", &t); while (t--) {scanf ("%d", &n); int I, j, K; for (i = 0; i < n; i++) {scanf ("%d", &l[i]); } for (i = 0; i < n; i++) {scanf ("%d", &r[i]); E[i].clear (); } for (i = 0; i < n-1; i++) {scanf ("%d%d", &j, &k); j--; k--; E[j].push_back (k); E[k].push_back (j); } memset (Vis, false, sizeof (VIS)); memset (data, 0, sizeof (data)); Dfstree (-1, 0); Print (); DFS (-1, 0, 0); for (i = 0; i < n-1; i++) printf ("%d", ans[i]); printf ("%d\n", Ans[i]); } return 0;}
2014 Mudanjiang Field race F zoj 3824 fiber-optic Network