数字迷阵
題目描述
小可可參觀科學(xué)博物館時(shí),看到一件藏品,上面有密密麻麻的數(shù)字,如下所示: 1 2 3 5 8 13 21 34 55 89 144 ... 4 7 11 18 29 47 76 123 199 322 521 ... 6 10 16 26 42 63 110 178 288 466 754 ... 9 15 24 39 63 102 165 267 432 699 1131 ... 12 20 32 52 84 136 220 356 576 932 1508 ... 14 23 37 60 97 157 254 411 665 1076 1741 ... 17 28 45 73 118 191 309 500 809 1309 2118 ... 19 31 50 81 131 212 343 555 898 1453 2351 ... 22 36 58 94 152 246 398 644 1042 1686 2728 ... 25 41 66 107 173 280 453 733 1186 1919 3105 ... 27 44 71 115 186 301 487 788 1275 2063 3338 ... ... 仔細(xì)一分析,發(fā)現(xiàn)還挺有規(guī)律。 原來,第一行是Fibonacci數(shù)列。即,該行中除了第一個(gè)和第二個(gè)數(shù)分別為1和2之外,其他數(shù)都是其左側(cè)相鄰的兩個(gè)數(shù)之和。 其后各行也類似于Fibonacci數(shù)列。只是第i行的第一個(gè)數(shù)是前 行中未出現(xiàn)的最小正整數(shù),而其第二個(gè)數(shù)與該行第一個(gè)數(shù)以及所在行的編號(hào)相關(guān),即A[i,2]=A[i,1]*2-(i-1) 。如在第一行中未出現(xiàn)的最小正整數(shù)為4,前三行中未出現(xiàn)的最小正整數(shù)為9。故第二行以4和7開頭,而第四行以9和15開頭。 小可可高興地把這個(gè)發(fā)現(xiàn)告訴了爺爺。爺爺問道:你能否一口報(bào)出第i行、第j列的那個(gè)數(shù)對(duì)m取模的結(jié)果是多少呢? 聰明的小可可通過心算就能知道答案。你是否能編寫程序求解呢?輸入
每行有三個(gè)分別用一個(gè)空格隔開的正整數(shù),分別是i、j和m。其中,i, j<=1000000000 ,2<=m<=10000 。輸出
每行輸出對(duì)應(yīng)的第i行、第j列的那個(gè)正整數(shù)對(duì)m取模的結(jié)果。樣例輸入
1 2 99樣例輸出
2【分析】
這題賊強(qiáng)啊,想了好久還是沒搞出來啊。最原始的想法顯然是直接搞出第一項(xiàng)啊。顯然是可以用暴力的。但是數(shù)據(jù)量太大了,數(shù)組肯定是開不了的。所以直接放棄了。然后就是找規(guī)律了。按照上面給的一個(gè)表,可以很明顯的發(fā)現(xiàn),如果只看首項(xiàng)的話,顯然有每?jī)尚兄g的差值是2或者3,然后我就寫了一發(fā)暴力程序,弄出了前面兩百項(xiàng),however,雖然都是2和3,但是2,3出現(xiàn)的毫無規(guī)律,如果說有的話,可能就是3比2多(-_-!)。然后就沒辦法了,只有問大佬怎么搞得,終于學(xué)到了。說是什么斐波那契最小拆分。果然強(qiáng)啊。
首先,對(duì)于第i行來說,你用fibonacci數(shù)列里面的數(shù)來表示i-1,轉(zhuǎn)換成二進(jìn)制,然后在后面加上兩個(gè)數(shù)0,1。然后對(duì)應(yīng)到fibonacci里面去求和。就得到了首項(xiàng)。舉個(gè)栗子:
對(duì)于第5行來說,你先弄出i-1,也就是4,4用fibonacci數(shù)列來表示就是101(也就是1+3),然后加上01,變成10101(也就是1+3+8=12),所以第五行第一列就是12。雖然我也不知道為啥。
然后剩下的事就是矩陣快速冪的事了。輕松水過。
【代碼】
#include<iostream> #include<cstdio> #include<cstring> #include<string.h> #include<algorithm> #include<vector> #include<cmath> #include<stdlib.h> #include<time.h> #include<stack> #include<set> #include<map> #include<queue> #include<sstream> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS_1(a) memset(a,-1,sizeof(a)) #define MSinf(a) memset(a,0x3f,sizeof(a)) #define sin1(a) scanf("%d",&(a)) #define sin2(a,b) scanf("%d%d",&(a),&(b)) #define sin3(a,b,c) scanf("%d%d",&(a),&(b),&(c)) #define sll1(a) scanf("%lld",&(a)) #define sll2(a,b) scanf("%lld%lld",&(a),&(b)) #define sll3(a,b,c) scanf("%lld%lld%lld",&(a),&(b),&(c)) #define sdo1(a) scanf("%lf",&(a)) #define sdo2(a,b) scanf("%lf%lf",&(a),&(b)) #define sdo3(a,b,c) scanf("%lf%lf%lf",&(a),&(b),&(c)) #define pin1(a) printf("%d",(a)) #define pin2(a,b) printf("%d%d",(a),(b)) #define pin3(a,b,c) printf("%d%d%d",(a),(b),(c)) #define pll1(a) printf("%lld",(a)) #define pll2(a,b) printf("%lld%lld",(a),(b)) #define pll3(a,b,c) printf("%lld%lld%lld",(a),(b),(c)) #define pdo1(a) printf("%f",(a)) #define pdo2(a,b) printf("%f%f",(a),(b)) #define pdo3(a,b,c) printf("%f%f%f",(a),(b),(c)) #define huiche puts("") #define inf 0x3f3f3f3f //#define lson i<<1,l,mid //#define rson ((i<<1)|1),mid+1,r #define uint unsigned int typedef pair<int,int> PII; #define A first #define B second #define pb push_back #define MK make_pair #define ll long long template<typename T> void read1(T &m) {T x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}m = x*f; } template<typename T> void read2(T &a,T &b) {read1(a);read1(b); } template<typename T> void read3(T &a,T &b,T &c) {read1(a);read1(b);read1(c); } template<typename T> void out(T a) {if(a>9) out(a/10);putchar(a%10+'0'); } template<typename T> void outn(T a) {if(a>9) out(a/10);putchar(a%10+'0');puts(""); } ///------------------------------------------------------------------------------------------------------------------ long long fbonacci[50]; long long mod; void init(void) {long long last = 0;long long now = 1;rep0(i,0,50) {fbonacci[i]=now;int t = now;now+=last;last = t;} } long long get(long long ind) {long long ret =1;rep_1(i,49,0){if(ind>=fbonacci[i]){ret += fbonacci[i+2];ret%=mod;ind-=fbonacci[i];}}return ret; } struct juzhen {int m[2][2]; }; juzhen mul(juzhen a,juzhen b) {juzhen c;MS0(c.m);rep0(i,0,2)rep0(j,0,2)rep0(k,0,2){c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[j][k])%mod;}return c; } juzhen my_pow(juzhen a,long long b) {juzhen c;rep0(i,0,2)rep0(j,0,2)c.m[i][j]=(i==j);while(b){if(b&1)c = mul(c,a);a = mul(a,a);b>>=1;}return c; } int main() { // freopen("in.txt","r",stdin);init();long long i,j;while(sll3(i,j,mod)!=EOF){long long f1 = get(i-1);long long f2 = (f1*2-i+1)%mod;if(j==1){pll1(f1);huiche;continue;}if(j==2){pll1(f2);huiche;continue;}juzhen a;rep0(i,0,2) rep0(j,0,2) a.m[i][j]=1;a.m[1][1]=0;a = my_pow(a,j-2);printf("%lld\n",(a.m[0][0]*f2+a.m[0][1]*f1)%mod);}return 0; }總結(jié)
- 上一篇: 迷阵突围
- 下一篇: 百度网盘不限速下载每秒6兆左右之Prox