這道題的方法很簡單,關鍵在於這道題有很多角度都能切入思考,能不能快速想到合適的解法。
方法步驟:
將k化為二進位制,則對應bit位置若為0,則a1,a2,...,an相應的bit位設為b1,b2,...,bn。相鄰2個bi不能同時為1。考慮這樣情況的總數。
既然不能出現連續的1。設方法總數為f(n),bn為1時,b(n-1)為0,此時方法數為f(n-2)。當bn為0時,方法數為f(n-1)。
則利用數學歸納法,很容易得到:f(n) = f(n-1)+f(n-2)。初始條件可令f(0)=1,f(1)=2,從而有f(2)=3。
最終答案
其中count為k數字二進位制裡1的數量。
最終求解的時候,f(n)可以用矩陣快速冪log(n)求解,並且可以發現是菲波拉契數列。並且所有涉及到的冪次方都可以用快速冪進行求解。
最後要注意:
1.取余要注意最後結果是負數的話要變為正數
2.當2^l-1比k小的時候,方案數為0。
#include __int64 n, k, tmp, l, m, myresult, tmp1, mycount, fn, mymaxsize;
#define mymaxsize1 9223372036854775807 //2^63-1
void mymultiply(__int64 a[2][2], __int64 b[2][2], __int64 c[2][2])
} }for (i = 0; i < 2; ++i) }
}void getmypowermod(__int64 x, __int64 y, __int64 m, __int64 &result)
y >>= 1;
tmp1 = (tmp1 * tmp1) % m; }}
void bit1count(__int64 x, __int64 &result)
}void getfib(__int64 n, __int64 &result)
n >>= 1;
mymultiply(c, c, c);
} result = resultarray[0][1];
}int main() }
bit1count(k, mycount);
getfib(n, fn);
getmypowermod(2, n, m, tmp1);
getmypowermod(tmp1 - fn, mycount, m, myresult);
getmypowermod(fn, l - mycount, m, tmp);
myresult = (myresult * tmp) % m;
if (myresult<0)
printf("%lld", myresult);
for (int i = 1; i <= 10; ++i)
return 0;
}
poj 1186 方程的解數
方程的解數 time limit 15000ms memory limit 128000k total submissions 6393 accepted 2198 case time limit 5000ms description 已知乙個n元高次方程 其中 x1,x2,xn是未知數,k1,k2...
poj 1186 方程的解數
題目描述如下 總時間限制 15000ms 記憶體限制 128000kb 描述 已知乙個n元高次方程 其中 x1,x2,xn是未知數,k1,k2,kn是係數,p1,p2,pn是指數。且方程中的所有數均為整數。假設未知數1 xi m,i 1,n,求這個方程的整數解的個數。1 n 6 1 m 150。方程...
POJ 1186 方程的解數
一道資料結構的水題。題意為給予乙個最多含六個未知數的方程k1 x1 p1 k2 x2 p2 k3 x3 p3 k4 x4 p4 k5 x5 p5 k6 x6 p6 0 求其整數解的個數。其中x1,x2.x6均大於等於1小於等於m m為輸入的乙個正數,最大150最小1 而且保證過程計算小於2 31。到...