首先不難列出乙個o(
n⋅262
) o(n
⋅262)
的dp方程: 設f
i,c fi,
c表示權值最多為
i i
,結尾字元為
c' role="presentation" style="position: relative;">c
c的方案數,vx
,yv x,
y為x,
y x,y
的差異值,那麼有 fi
,c=1
+∑fi
−vc,
d,d fi,
c=1+
∑fi−
vc,d
,d
注意到vx
,y≤5
v x,
y≤
5,那麼如果把i i
相同的狀態看成一行,把每
5' role="presentation" style="position: relative;">5
5行合成一塊,那麼某一塊的狀態要麼從上一塊轉移過來,要麼從當前塊轉移過來,這樣就可以矩陣快速冪優化了。
具體的,假設fy
→fx fy→
fx
(yy 和
x' role="presentation" style="position: relative;">x
x是兩維狀態壓成一維),若fy
f
y在上一塊就直接在係數ax
,ya x,
y上+
1 +1
,若在當前塊就把ay
,...
a y,
..
.加到a
x,..
. ax,.
..
即可。
複雜度o((
5⋅26)
3logn)
o ((
5⋅26)
3logn
)。 **:
#include
#include
#include
#define up(x,y) (x=(x+(y))%mod)
#define ll long long
#define g(x,y) ((x)*26+(y))
using
namespace
std;
const
int mod=1000000007;
int n,m,v[30][30];
struct matrix
matrix operator *(matrix &b)
}f(131,1),g(131,131);
matrix ksm(matrix t,ll b)
return re;
}int main()
for(int i=0;i<=130;i++)
f.a[i][0]=g.a[i][130]=1;
for(int i=0;i<=4;i++)
for(int c=0;c<26;c++)
}f=ksm(g,n/5)*f;
ll ans=0;
for(int c=0;c<26;c++)
up(ans,f.a[g(n%5,c)][0]);
printf("%lld",ans);
return0;}
BZOJ 4547 矩陣快速冪
思路 肯定每回只加最大值和次大值 如果 一開始的最大值 0且次大值 0 那就一直加 加到次大值 0 搞乙個矩陣 推斐波那契數列 求和 就好 by siriusren include include include using namespace std const int mod 10000007,...
bzoj1009矩陣快速面 kmp
其實kmp真的很次要,求長度為20的kmp感覺真的有點殺雞用牛刀 這題思路相當明確 一看題就是數字dp,一看n的大小就是矩陣 矩陣的構造用m m比較方便,本來想寫1 m的矩陣乘m m的,但是感覺想起來太麻煩就偷懶,沒想到1a了 log的速度的確可以,87ms賊快,好久沒見這麼短的執行時間了 1 in...
bzoj1009(kmp,dp,矩陣乘法,快速冪)
description 阿申準備報名參加gt考試,准考證號為n位數x1x2 xn 0 xi 9 他不希望准考證號上出現不吉利的數字。他的不吉利數學a1a2 am 0 ai 9 有m位,不出現是指x1x2 xn中沒有恰好一段等於a1a2 am.a1和x1可以為 0input 第一行輸入n,m,k.接下...