有乙個 $n$ 個點構成的有向圖。
對於每乙個點 $i$ ,給定兩組引數,每組引數分別有 $k$ 個值。這兩組引數分別記做: $in[i][1\cdots k],out[i][1\cdots k]$ 。
從點 $i$ 連到點 $j$ 的邊數定義為 $\sum_^k in[i][t]\times out[i][t]$ 。
$m$ 組詢問,每次詢問從 點 $x$ 走到點 $y$ ,經過不超過 $d$ 條邊的方案總數。
$n\leq 1000,m\leq 50,k\leq 20,d\leq 2^-1$
首先我們選取 $k$ 個中介點,很容易得到乙個由原圖的 $n$ 個點轉移到這 $k$ 個點的方案數的轉移矩陣 $\mathbf o$;類似的,可以得乙個由 $k$ 個中介點轉移到原圖的 $n$ 個點的方案數的轉移矩陣 $\mathbf i$ 。
假設我們要求的是恰好經過 $d$ 條路徑的方案數,那麼,顯然,我們只需要求出 $(\mathbf)^d$ 的第 $i$ 行第 $j$ 列的值即可。
但是我們發現這個矩陣是 $1000\times 1000$ 的,複雜度顯然不行。我們發現 $k$ 非常小,而且矩陣 $\mathbf $ 的長寬都是 $k$ 。
由於矩陣乘法具有結合律,所以我們可以把原式寫成:
$\mathbf (\mathbf)^d \mathbf$ 這樣時間複雜度就對了。
但是原題要求的是不超過 $d$ 步的。
考慮新增乙個點,這個點只能走到自己,將詢問中的終點連向它即可。
#pragma gcc optimize("o2")#include using namespace std;
const int n=1005,k=25,mod=1e9+7;
struct mat
mat(int _r,int _c,int x)
void print()
};mat operator * (mat a,mat b)
mat pow(mat x,int y)
int read()
int n,m,k;
mat i,o,m,res;
int main()
i.v[0][0]=o.v[0][0]=1;
m=read();
while (m--)
return 0;
}
BZOJ3583 傑杰的女性朋友 矩陣快速冪
時間限制 10s 空間限制 256mb 傑杰是魔法界的一名傳奇人物。他對魔法具有深刻的洞察力,驚人的領悟力,以及令人嘆為觀止的創造力。自從他從事魔法競賽以來,短短幾年時間,就已經成為 世界公認的實力最強的魔法選手之一。更讓人驚嘆的是,他幾乎沒有借助外界力量,完全憑藉自己的努力達到了普通人難以企及的高...
BZOJ1052 BZOJ3760 覆蓋問題
原題位址 先說自己的逗比方法 二分答案,把所有點用乙個最小的矩形 框 起來,易證矩形的其中乙個端點是最優解中正方形的乙個端點,然後列舉四個端點後遞迴處理,差不多了 然後 olz黃學長的o n 做法 ac code include include include using namespace std...
動態點分治 bzoj 3730,bzoj 1095
總結一下動態點分治的模板。對於乙個樹,把它點分的同時記錄每個點的所有父親 logn個 並記錄點距其父親的距離。具體實現就是dfs的時候fa x dep x u,dis x dep x d bzoj1095 您需要寫乙個程式支援反轉點的顏色,求距離最遠的黑色點對的距離。解析 在每個點u存乙個堆st記錄...