LOJ10163 Amount of Degrees
阿新 • • 發佈:2018-12-27
題目描述
求給定區間 [X,Y] 中滿足下列條件的整數個數:這個數恰好等於 KK 個互不相等的 BB 的整數次冪之和。例如,設 X=15,Y=20,K=2,B=2,則有且僅有下列三個數滿足題意
輸入格式
第一行包含兩個整數 X 和 Y,接下來兩行包含整數 K 和 B。
輸出格式
只包含一個整數,表示滿足條件的數的個數。
樣例
樣例輸入
15 20
2
2
樣例輸出
3
資料範圍與提示
對於全部資料,1≤X≤Y≤2^31−1,1≤K≤20,2≤B≤10。
______________________________________________________________________________________________
數位動歸
一類區間統計問題,區間較大,無法用暴力求解或組合數學求解。
常見為求區間內滿足某類條件的X進位制數的個數。條件往往與數位有關。
此題:
首先,區間具有相減的性質。count[i...j]=count[ 0...j ] - count[ 0...i-1 ]。
這樣問題就變成了0到i的x進位制數有多少個滿足條件。
因為是互不相等的k進位制數,所以,轉成k進位制後,每個位上要麼是0要麼是1。
這樣f[i][j]表示長度I的2進位制數,有j個1的種類
f[i][j]=f[i-1][j]+f[i-1][j-1]
______________________________________________________________________________________________
1 #include<bits/stdc++.h> 2 using namespace std; 3 int x,y,k,b; 4 int wei[32]; 5 int f[32][32]; 6 void prech(int &x,int b) 7 { 8 int js=0; 9 while(x>0) 10 { 11 wei[++js]=x%b; 12 x/=b; 13 } 14 while(js>0) 15 { 16 if(wei[js]==1)x^=1<<(js-1); 17 else if(wei[js]>1) 18 { 19 for(int i=js;i>0;--i)x^=1<<(i-1); 20 break; 21 } 22 --js; 23 } 24 } 25 void dp() 26 { 27 f[0][0]=1; 28 for(int i=1;i<=31;++i) 29 { 30 f[i][0]=f[i-1][0]; 31 for(int j=1;j<=i;++j)f[i][j]=f[i-1][j]+f[i-1][j-1]; 32 } 33 } 34 int work(int x,int k) 35 { 36 int js=0,ans=0; 37 for(int i=31;i>0;--i) 38 { 39 if(x&(1<<i)) 40 { 41 ++js; 42 if(js>k)break; 43 x=x^(1<<i); 44 } 45 if((1<<(i-1))&x)ans+=f[i-1][k-js]; 46 } 47 if(js+x==k)ans++; 48 return ans; 49 } 50 int main() 51 { 52 scanf("%d%d%d%d",&x,&y,&k,&b); 53 x--; 54 prech(x,b);prech(y,b); 55 dp(); 56 cout<<work(y,k)-work(x,k); 57 return 0; 58 }View Code