日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【2012 Semifinal 1】 YetAnotherNim

發布時間:2023/12/14 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【2012 Semifinal 1】 YetAnotherNim 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

現在有一個博弈游戲。
有n堆石子,每堆石子的數量在??之間,其中?.
先手先從中選出連續K堆石子,刪掉其他的所有堆。
后手接著刪去任意堆石子,可以不刪,但是不能全刪。
然后兩人開始玩NIM游戲。
求后手必勝的初始局面數量。

Difficulty

★★★

Main Algorithm

DP 矩乘加速
線性代數
博弈論

Complexity

Solution

挺有意思的。
我們發現關鍵是后手刪去任意堆石子后,剩下的石子異或和為0.
即先手取了任意連續K堆石子后,都存在一組數使得異或和為0.
那么就繼續用線性代數來描述。題目變為求長度為n,每個數均在1~m之間,任意連續K個數線性相關的序列個數。
顯然的當??的時候,任意K個數必然是線性相關的,那么答案就是?
當??的時候,直接做似乎不好做,線性相關這個東西看上去并不容易壓入狀態。
那么補集轉化為求存在某K個數線性無關的序列個數。
這樣,對線性無關的討論似乎更方便,因為線性無關組中一個數所控制的位僅一位。
設??表示考慮了前i個數,且恰好后j個數線性無關的序列個數。
考慮新加入一個數。
假如這個數與后j個數都線性無關,那么除了只在這j位為1的數之外,都可以選。
.
假如這個數與后v個數線性無關,但是與后v+1個數線性相關:
那么這個數在從后數第v+1個數控制的位上是1,除了后v+1個數控制的位,別的都不能為1(若在除了這v+1位上有1,則會導致這個數對于后v+1個數線性無關)。
.
而??不能往別的狀態上轉移了,但i后面的數就能任取了。其對答案的貢獻為?.
考慮用矩陣乘法加速。
前面的那一大堆的系數都是常數。唯有向答案貢獻的地方乘的是?。怎么辦呢?考慮最后的答案是個關于m的多項式,每個系數就是?,那么用秦九韶算法展開后,所有系數便都變為常數了。


#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <cmath> #define Rep(i, x, y) for (int i = x; i <= y; i ++) #define Dwn(i, x, y) for (int i = x; i >= y; i --) #define RepE(i, x) for(int i = pos[x]; i; i = g[i].nex) using namespace std; typedef long long LL; const int N = 105, mod = 1000000007; int u = 1, u1, n; LL A0, s2[N]; struct Matr {LL a[N][N];Matr() { memset(a, 0, sizeof(a)); } } p, q; Matr operator* (Matr x, Matr y) {Matr z;Rep(i, 1, n)Rep(k, 1, n)Rep(j, 1, n) (z.a[i][j] += x.a[i][k] * y.a[k][j]) %= mod;return z; } class YetAnotherNim { public:void Pow(int x) {while (x) {if (x & 1) q = q * p;p = p * p, x >>= 1;}}int pow2(LL x, int y) {LL z = 1;while (y) {if (y & 1) (z *= x) %= mod;y >>= 1, (x *= x) %= mod;}return z;}int solve(int T, int m, int n0) {n = n0, A0 = pow2(m, T);while (u <= m) u *= 2, u1 ++;if (n == 1) return 0;if (n > u1) return A0;// puts("fin");s2[0] = 1;Rep(i, 1, n - 1) {s2[i] = s2[i - 1] * 2 % mod;Rep(j, 1, i) p.a[i][j] = s2[j - 1];p.a[i][i + 1] = (m + 1 - s2[i] + mod) % mod;} p.a[n][n] = m;q.a[1][1] = m;Pow(T - 1); // cout << A0 << endl;return int((A0 - q.a[1][n] + mod) % mod);} };

總結

以上是生活随笔為你收集整理的【2012 Semifinal 1】 YetAnotherNim的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。