codefroces 852B - Neural Network country
阿新 • • 發佈:2017-09-04
roc spa 自己 while lan define nod color void
http://codeforces.com/contest/852/problem/B
題意:有一幅有向圖,除了源點和匯點有 L 層,每層 n 個點。 第 i+1 層的每個點到 第 i+2 層的每個點都有一條邊,邊的權值為有向邊終點的權值。求源點到匯點的路徑長度能被 m 整除的個數。
題解:快速冪。a[i] 表示從第 1 層到第 a 層總路徑長度為 i (i % m) 的數目,b[j] 表示從第 a+1層到 第 a+1 層(也就是自己層)總路徑長度為 j (j % m) 的數目,那麽第 a+2 層的 a[(i+j)%m] = a[i]*b[j]。
暴力做法,從第一層開始,一層一層的乘上去,這樣顯然會超時。
仔細看一下,從第 2 層到第 L-1 層,每次乘的操作是相同的,可以用快速冪先把第 2 層到第 L-1 層乘起來。
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define mod 1000000007 using namespace std; const int MAXN = 100000+10; int a[1000010]; int n, l, m; struct node { long long num[110]; node() { memset(num,0x0000, sizeof(num)); } }; node Begin, End, mid; node mul(node la, node lb) { node aa = node(); for(int i = 0; i < m; i++) { for(int j = 0; j < m; j++) { int k = (i+j)%m; aa.num[k] += la.num[i] * lb.num[j] % mod; aa.num[k] %= mod; } }return aa; } node fast(node nod, int k) { node sum = nod; k--; while(k) { if(k&1) { sum = mul(sum, nod); } k >>= 1; nod = mul(nod, nod); } return sum; } int main (void) { ios::sync_with_stdio(false); Begin = node(); End = node(); mid = node(); cin >> n >> l >> m; for(int i = 1; i <= n; i++) { int x; cin >> x; Begin.num[x%m]++; } for(int i = 1; i <= n; i++) { int x; cin >> x; a[i] = x; mid.num[x%m]++; } for(int i = 1; i <= n; i++) { int x; cin >> x; End.num[(x+a[i])%m]++; } node nod; if( l-2 > 0 ) { nod = fast(mid, l-2); nod = mul(nod, Begin); nod = mul(nod, End); } else { nod = mul(Begin, End); } long long ans = 0; for(int j = 0; j <= 100; j++) { if(j%m==0) { ans += nod.num[j]; ans %= mod; } } cout << ans; }
codefroces 852B - Neural Network country