今天,MM在上數學課,數學課的主題是函數。講完之後老師留了一個家庭做業,讓同窗們回家思考。題目以下:程序員
定義一個函數,F(x)表示x轉成二進制後,二進制中「1」的個數。好比F(279)=5,由於(279)10=( 100010111)2,其中有5個「1」。數組
如今有一個序列,已知X0 = 0,Xi=F(Xi-1)*A+B。老師的問題是求這個序列第K個是多少。函數
輸入3個整數,A,B,K,定義如上所述。spa
輸出只有一行,序列的第K個的值。code
1blog
7數學
2io
10class
0≤A,B≤ 1,000,000二進制
30% 數據1≤K≤1,000,000
100% 數據1≤K≤1,000,000,000
打幾個表,而後就發現當K足夠大的時候答案就造成一條鏈加一個環,直接模擬的時間就浪費在這個環上。
找出這個環,求出環的大小並記錄環的每個元素,K減去鏈的長度,對環的大小取模獲得的就是答案在環中的位置。
數組範圍開多大?
打開電腦上的計算器,使用程序員型,把106轉換成二進制,有20位,那麼f(x)的值不會超過20,f(x)*A+B的值不超過20*106+106= 21000000
因此數組範圍開21000000
1 #include <cstdio> 2 int A,B,K,f[21000005],t=1,h,max; // f[1]=0 3 bool vis[21000005]; 4 int main() 5 { 6 int x=0,i,j,cnt,p; 7 scanf("%d%d%d",&A,&B,&K); 8 vis[0]=1; 9 while (K--) 10 { 11 for (cnt=0;x;x-=(x&(-x))) cnt++; 12 x=cnt*A+B; 13 if (x>max) max=x; 14 if (!vis[x]) vis[x]=1,f[++t]=x; 15 else break; 16 } 17 if (++K) 18 { 19 for (h=1;f[h]!=x;h++); 20 p=K%(t-h+1); 21 if (!p) printf("%d",f[t]); 22 else printf("%d",f[p+h-1]); 23 } 24 else printf("%d",x); 25 return 0; 26 }