bzoj1009(kmp,dp,矩陣乘法,快速冪)

2021-08-25 10:59:19 字數 1778 閱讀 3999

description

阿申準備報名參加gt考試,准考證號為n位數x1x2….xn(0<=xi<=9),他不希望准考證號上出現不吉利的數字。

他的不吉利數學a1a2…am(0<=ai<=9)有m位,不出現是指x1x2…xn中沒有恰好一段等於a1a2…am. a1和x1可以為

0input

第一行輸入n,m,k.接下來一行輸入m位的數。 n<=10^9,m<=20,k<=1000

output

阿申想知道不出現不吉利數字的號碼有多少種,輸出模k取餘的結果.

sample input

4 3 100

111

sample output

81看上去很像容斥…

考慮dp fi

,jf i,

j表示前

i i

位,匹配了

j' role="presentation" style="position: relative;">j

j位的方案數

考慮下一位,有可能繼續匹配,有可能部分失陪,有可能全部失配 根據n

ext nex

t陣列構造轉移矩陣 快速冪優化即可

#include

using namespace std;

#define rep(i,j,k) for(int i = j;i <= k;++i)

#define repp(i,j,k) for(int i = j;i >= k;--i)

#define rept(i,x) for(int i = linkk[x];i;i = e[i].n)

#define p pair

#define pil pair

#define pli pair

#define pll pair

#define pb push_back

#define pc putchar

#define file(k) memset(k,0,sizeof(k))

#define ll long long

int n , len , pp;

char s[30];

int next[30];

struct martixg,a;

int read()

while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();

if(!flag) sum = -sum;

return sum;

} void init()

return;

}bool vis[30];

void make_martix()

int j = i;

while(j)

}g.f[i][0] = 10 - sum;

}g.f[len][len] = 10;

a.f[0][0] = 1;

return;

}void re(martix &now)

martix mul(martix a,martix b,int n,int m,int p)//n*p 和 p*m

return ans;

}martix pow(martix a,int k)

return now;

}int main()

bzoj1009矩陣快速面 kmp

其實kmp真的很次要,求長度為20的kmp感覺真的有點殺雞用牛刀 這題思路相當明確 一看題就是數字dp,一看n的大小就是矩陣 矩陣的構造用m m比較方便,本來想寫1 m的矩陣乘m m的,但是感覺想起來太麻煩就偷懶,沒想到1a了 log的速度的確可以,87ms賊快,好久沒見這麼短的執行時間了 1 in...

bzoj1009 GT考試 dp 矩陣快速冪

題意 構造乙個字串 數字0 9 不含乙個子串的個數 我這麼蒟蒻腫麼可能想到是dp嘛 定義f i j 表示當前構造了i位,與模式串p匹配了前j位的方案數 然後列舉下一位填什麼,然後乘上當前構造出來的和模式串匹配到k的方案數。即是f i 1 k f i j a j k 因為從j轉移到k,可以用的數字不一...

BZOJ 1009 GT考試 KMP 矩陣快速冪

題意 b為非法數字b 1 b m 其位數 20.某個數有n位,每位可以填入 0,9 n 1e9 問有多少種填數字方案,滿足n位中沒有非法數字m出現?先不考慮n範圍 則可以設定dp i j 表示放了合法放了前i位,其字尾j和非法的前j位相同的方法數.轉移狀態顯然是一位一位新增 顯然dp i 1 j 1...