【BZOJ 2323】 2323: [ZJOI2011]细胞 (DP+矩阵乘法+快速幂*)
2323: [ZJOI2011]細胞
Description
2222年,人類在銀河系外的某顆星球上發現了生命,并且攜帶了一個細胞回到了地球。經過反復研究,人類已經完全掌握了這類細胞的發展規律:
這種細胞最初的形態是“長條形”,一端是頭,一端是尾,中間是軀干。細胞內部含有一列密碼(你可以認為它是這種細胞的DNA)。密碼是一個長度為n的數字串,且僅含有1~9這9種數字,沿著細胞的軀干從頭到尾排列著。
首先,細胞會經歷一次分裂。細胞將沿軀干方向分裂成若干個球體,軀干將退化成絲狀物,連接著相鄰的球體。在分裂過程中,質量是均勻分布的。換句話說,若分裂成k個球體,每個球體的質量為原來的1/k。然而,密碼的分布是不確定的。若分割成k個球體,密碼會被切割成k段(每段長度至少為1),并按從頭到尾的順序分布在各個球體中。如圖,為其中一種合法的一次分裂:
接下來,細胞會經歷二次分裂。對于每個球體,其中會含有一小段密碼(注意他是有序的),我們把它看作一個十進制的數T。這個球體會被分割成T個小球體,并排成一排,之間用軀干退化成的絲狀物相連接,并且質量仍然是均勻分布的,每個小球體的質量都是原球體的1/T。至此,密碼已經發揮了它的作用,便消失了。如圖,為二次分裂:
最后,細胞會進行變異。相鄰小球體之間的絲狀物可能會退化掉,這兩個小球體便會以相切的方式直接連接。顯然,二次分裂后,除兩端外的每個小球體都有兩段絲狀物與其連接(頭尾兩端的小球體只有一段絲狀物與其相連)。對于每個小球體,必須至少退化一段與其相連的絲狀物,否則這個結構不穩定,會繼續變異。如圖,為一種穩定的變異:
現在,我們想知道,對于一個給定密碼的細胞,總共有多少種穩定的結構。兩種結構被認為相同,當且僅當他們擁有相同個數的小球體,從頭到尾每個小球體的質量相同,并且從頭到尾每對相鄰小球體之間的連接方式相同(都是通過絲狀物相連或都是通過相切直接相連)。你只需要回答這個結果?mod?1000000007即可。
Input
第一行為一個正整數n,表示細胞密碼的長度。
第二行共n個數字,為給定的細胞密碼,中間沒有空格。
Output
只包含一個整數,為細胞的種數?mod?1000000007的結果。
Sample Input
【樣例輸入一】1
1
【樣例輸入二】
1
5
【樣例輸入三】
2
11
Sample Output
【樣例輸出一】0
【樣例輸出二】
3
【樣例輸出三】
56
HINT
【數據規模】
對于5%的數據滿足,n ≤ 6;
對于25%的數據滿足,n ≤ 25;
對于60%的數據滿足,n ≤ 100;
對于70%的數據滿足,n ≤ 300;
對于100%的數據滿足,n ≤ 1 000。
Source
Day2
?
?
【分析】
好題?
感謝數學試卷讓我發現了這個可愛的斐波那契數列。。【hhh
然后【矩陣的指數不能mod phi[p]? 。。被奧爺爺d了。。。。
首先,第一步或第三步不同,則出來的結果一定不同【自己想為什么吧、、我就是這樣覺得的
對于第三步,他說一個球兩邊一定有一邊被縮了,其實就是n條邊,讓你選若干條不縮的邊,他們不相鄰(因為兩端的點是有一條邊,所以兩端的邊是不能選的)
這個模型就是數學試卷上的經典模型?f[n]=f[n-1]+f[n-2],就是枚舉第n個選還是不選,就是斐波那契數列。
第三步的判斷就搞定了。
對于第一第二步,就是把這個大數字分成很多部分,套上第三步的方案加入答案中,這個可以用DP處理。
f[x][0]表示x前面那條邊沒有選,
f[x][1]表示x前面那條邊選了。
? f[i][0]=f[i][0]+f[j][0]*F[nw-3]+f[j][1]*F[nw-2]
f[i][1]=f[i][1]+f[j][0]*F[nw-2]+f[j][1]*F[nw-1]?
//F表示斐波那契數列, nw表示j+1~i表示的數。
?
然后問題來了,F[nw???]怎么求,nw是個極大的數額。。
【一開始我以為矩陣冪的指數可以mod phi 還樂呵呵地打了。。。
其實可以預處理,但是傳統的快速冪的話,貌似,挺慢??而且你要高精??
傳統的快速冪是以2為底的快速冪,他給你的高精數是10進制下的,不如把快速冪改成10為底的,那么你可以發現,有些過程可以合并,比如你算[l,r]的f,中間已經算了[l,r-1]的部分。
所以預處理就是O(n^2*一個不知道多大的常數)
好像別人打的都挺快的。。。可以看看其他解法:http://www.cnblogs.com/cghAndy/p/6594538.html
?
總時間復雜度:O(n^2*一個不知道多大的常數)
?
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define LL long long 8 #define Mod 1000000007 9 #define Maxn 1010 10 11 int n; 12 13 struct node 14 { 15 LL w[3][3]; 16 }t[17],tt[3]; 17 18 LL a[Maxn],f[Maxn][2]; 19 char s[Maxn]; 20 21 void mul(int z,int x,int y) 22 { 23 t[2]=tt[0]; 24 for(int k=1;k<=2;k++) 25 for(int i=1;i<=2;i++) 26 for(int j=1;j<=2;j++) 27 t[2].w[i][j]=(t[2].w[i][j]+t[x].w[i][k]*t[y].w[k][j])%Mod; 28 t[z]=t[2]; 29 } 30 31 void qpow(int x,int b) 32 { 33 t[1]=tt[1]; 34 while(b) 35 { 36 if(b&1) mul(1,x,1); 37 mul(x,x,x); 38 b>>=1; 39 } 40 t[x]=t[1]; 41 } 42 43 LL B[Maxn][Maxn][3]; 44 45 LL get_f(int x) 46 { 47 t[3]=tt[2]; 48 t[4]=tt[1]; 49 for(int i=x;i<=n;i++) 50 { 51 qpow(4,10); 52 t[0]=t[3]; 53 qpow(0,a[i]); 54 // mul(4,a[i]-10,4); 55 56 t[5]=t[4]; 57 B[x][i][0]=t[5].w[1][1]; 58 mul(5,5,3); 59 B[x][i][1]=t[5].w[1][1]; 60 mul(5,5,3); 61 B[x][i][2]=t[5].w[1][1]; 62 } 63 } 64 65 void init() 66 { 67 tt[0].w[1][1]=0;tt[0].w[1][2]=0; 68 tt[0].w[2][1]=0;tt[0].w[2][2]=0; 69 70 tt[1].w[1][1]=1;tt[1].w[1][2]=0; 71 tt[1].w[2][1]=0;tt[1].w[2][2]=1; 72 73 tt[2].w[1][1]=0;tt[2].w[1][2]=1; 74 tt[2].w[2][1]=1;tt[2].w[2][2]=1; 75 76 t[11]=tt[1];t[5]=tt[1]; 77 for(int i=2;i<=9;i++) 78 { 79 mul(i,i-1,5); 80 } 81 } 82 83 int main() 84 { 85 init(); 86 scanf("%d",&n); 87 scanf("%s",s+1); 88 for(int i=1;i<=n;i++) a[i]=s[i]-'0'; 89 90 memset(f,0,sizeof(f)); 91 f[0][0]=1; 92 93 int i,j,k; 94 for(i=1;i<=n;i++) get_f(i); 95 96 for(i=1;i<=n;i++) 97 for(j=0;j<i;j++) 98 { 99 f[i][0]=f[i][0]+f[j][0]*B[j+1][i][0];f[i][0]%=Mod; 100 f[i][0]=f[i][0]+f[j][1]*B[j+1][i][1];f[i][0]%=Mod; 101 f[i][1]=f[i][1]+f[j][0]*B[j+1][i][1];f[i][1]%=Mod; 102 f[i][1]=f[i][1]+f[j][1]*B[j+1][i][2];f[i][1]%=Mod; 103 104 } 105 printf("%d\n",f[n][0]); 106 return 0; 107 } View Code?
2017-03-21?21:16:25
轉載于:https://www.cnblogs.com/Konjakmoyu/p/6596743.html
總結
以上是生活随笔為你收集整理的【BZOJ 2323】 2323: [ZJOI2011]细胞 (DP+矩阵乘法+快速幂*)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常吃五谷杂粮的好处
- 下一篇: 鹌鹑蛋剥坏了蛋黄漏出来了卤后卤水会坏吗?