ural 1057Amount of Degrees ——数位DP
August 20, 2013
DP
link:http://acm.timus.ru/problem.aspx?space=1&num=1057
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <queue>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <vector>
#include <utility>
#include <functional>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <numeric>
#include <cassert>
#include <ctime>
#include <iterator>
const int INF = 0x3f3f3f3f;
const int dir[8][2] = {{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}};
using namespace std;
int a[33][33];
int bto2(int x, int b)
{
int tm[33], cnt = 0, ans = 0;
while (x)
{
tm[cnt++] = x % b; x /= b;
}
for (int i = cnt - 1; i >= 0; --i)
{
if (tm[i] && (tm[i] != 1))
{
ans += ((1<<(i+1))-1); break;
}
else if(tm[i]) ans += (1<<i);
}
return ans;
}
int calc(int x, int k)
{
int tot = 0, ans = 0;
for (int i = 31; i > 0; --i)
{
if (x & (1<<i))
{
++tot; if (tot > k) break;
x = x ^ (1<<i);
}
if ((1<<(i - 1)) <= x) ans += (a[i-1][k-tot]);
}
if (tot + x == k) ++ans;
return ans;
}
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin );
#endif // ONLINE_JUDGE
int x,y,k,b;
memset(a, 0, sizeof(a));
a[0][0] = 1;
for (int i = 1; i <= 31; ++i)
{
a[i][0] = a[i-1][0];
for (int j = 1; j <= i; ++j) a[i][j] = a[i-1][j] + a[i-1][j-1];
}
while (~scanf("%d%d%d%d",&x, &y, &k, &b))
{
long long int ans = 0;
if (b == 2)
{
ans = calc(y, k) - calc(x - 1, k);
}
else
{
int X = bto2(x - 1, b), Y = bto2(y, b);
ans = calc(Y, k) - calc(X, k);
}
printf("%lld\n", ans);
}
return 0;
}
走吧,小胖!