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