WOJ26 Lost in WHU 矩陣快速冪

2021-07-30 12:46:55 字數 3706 閱讀 2526

分類:matrixmath

[woj26 lost in whu]

給定乙個

n 個頂點的對稱矩陣g(

1≤n≤

100)

,aij

表示可以從點

i 一步到點

j,求在

t 時刻之前能從1到

n 的方案數。(1

≤t≤10

9)注意:如果在時刻tx

已經到達了點

n ,則終止。

題意是求在0,

1,2,

3,…,

t時刻到達

n 點的方案之和。

可以這麼考慮,求經過tx

步達到的

n 點的方案數可以這麼計算,tx

−1步是在1,2

,3,…

,n−1

這幾個頂點中走,最後一步再走到

n 點。

那麼,問題就很簡單的轉化為熟悉的矩陣快速冪了,經過tx

步達到的

n 點的方案數就是除去點

n的鄰接矩陣的tx

−1次方,然後加上最後一步的情況。

問題現在轉化為對矩陣冪求和了,即求矩陣∑t

−1i=

0ai 。 設s

x=∑x

−1i=

0ai 。

下面是求sx

的3種做法:

最後這個題目矩陣挺大的。遞迴一多肯定爆棧,所以可以必須用全域性變數或靜態變數。推薦用靜態變數返回引用值來做,簡單易實現,效率還高。

/** 法一:構造矩陣法 **/

#include

using

namespace

std;

typedef

long

long ll;

typedef

long

double lb;

typedef pair pii;

typedef pairpll;

typedef

vector

vi;

const

int inf = 0x3f3f3f3f;

const ll infl = 0x3f3f3f3f3f3f3f3fll;

const

double eps = 1e-8;

const

double pi = acos(-1.0);

const

int maxn = 100000 + 5;

const

int mx = 100 + 1;

const

int mod = 1e9 + 7;

int n, m, t, msz;

struct mat

void e()

mat& operator * (const mat& e) const }}

return ret;

}mat& operator ^ (int b) const

return ret;

}void p() const

puts("");}}

} init, tran, ans;

int g[mx];

int main()

for(int i = n; i <= msz; ++i)

for(int i = 1; i <= m; ++i)

tran.d[u][v] = ++ tran.d[v][u];

}scanf("%d", &t);

tran = (tran ^ (t - 1));

ans = tran * init;

ll rs = 0;

for(int i = 1; i <= (n - 1); ++i)

printf("%lld\n", rs);

#ifdef ___local_wonzy___

cout

<< "time elapsed: "

<< 1.0 * clock() / clocks_per_sec * 1000

<< " ms."

<< endl;

#endif // ___local_wonzy___

return

0;}

/** 法二:分治法 **/

#include

using

namespace

std;

typedef

long

long ll;

typedef

long

double lb;

typedef pair pii;

typedef pairpll;

typedef

vector

vi;

const

int inf = 0x3f3f3f3f;

const ll infl = 0x3f3f3f3f3f3f3f3fll;

const

double eps = 1e-8;

const

double pi = acos(-1.0);

const

int maxn = 100000 + 5;

const

int mx = 100 + 1;

const

int mod = 1e9 + 7;

int n, m, t;

struct mat

void e()

mat& operator * (const mat& e) const }}

return ret;

}mat& operator ^ (int b) const

return ret;

}mat& operator + (const mat& e) const

}return ret;

}void p() const

puts("");}}

} init, tran, ans;

int g[mx];

mat& ask(const mat& a, int b)

int md = (b >> 1);

ret = ask(a, md);

ret = ret + ret * (a ^ md);

if(b & 1) ret = ret + (a ^ (b - 1));

return ret;

}int main()

tran.d[u][v] = ++ tran.d[v][u];

}scanf("%d", &t);

ans = ask(tran, t);

ll rs = 0;

for(int i = 1; i <= (n - 1); ++i)

printf("%lld\n", rs);

#ifdef ___local_wonzy___

cout

<< "time elapsed: "

<< 1.0 * clock() / clocks_per_sec * 1000

<< " ms."

<< endl;

#endif // ___local_wonzy___

return

0;}

WOJ 654 遞推 矩陣快速冪

654.a math problem time limit 1000 ms mem.limit 524288 kib io stdio given a number nn n,you should calculate 123456 11121314 n123456 ldots 11121314 ld...

2 6陣列運算和矩陣運算

1 陣列和標量的運算 陣列可以和乙個標量 1x1的矩陣 進行加 減 乘 除運算,其結果將是此標量和陣列中的每乙個元素 相加 相減 相乘 相除 而經典數學中矩陣和乙個標量不能進行加 減運算,只允許矩陣和乙個標量進行乘 除運算,並進行相除運算時,標量必須是除數,矩陣為被除數。2 乙個標量與乙個陣列的乘運...

26 WebGL的透視投影矩陣

上一章講的盒狀投影矩陣,主要用於精度需求度高的工業。而這一節的透視投影矩陣,更符合我們正常人的視覺,也是就近大遠小的感覺。我們需要實現的效果就是同樣大小的圖形,距離視點越遠,展現出來就越小,如圖 就像盒狀可視空間那樣,透視投影可視空間也有視點 視線 近裁剪面和遠裁剪面,這樣可視空間內的物體才會被現實...