1. 程式人生 > >codefroces 852B - Neural Network country

codefroces 852B - Neural Network country

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