您的位置:首页 > 其它

SPOJ 1182 数位DP+二分

2013-03-26 16:09 453 查看
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define LL long long
int dp[33][33];
void init() {
int i, j;
dp[0][0] = 1;
for(i = 1; i <= 32; i++)
for(j = 0; j <= i; j++) {
dp[i][j] += dp[i-1][j];
if(j) dp[i][j] += dp[i-1][j-1];
}
}
void gao(LL n, int *f) {
int a[33], len = 0;
int i, j, k;
while(n) {
a[len++] = n&1; n >>= 1;
}
f[0]++;
for(i = len-1; i >= 1; i--)
for(k = 1; k <= i; k++)
f[k] += dp[i-1][k-1];

int cnt = 0;
for(i = len-1; i >= 0; i--) {
for(j = (len-1 == i) ? 1 : 0; j < a[i]; j++)
for(k = cnt; k <= 32; k++)
f[k] += dp[i][k-cnt];
if(a[i]) cnt++;
}

f[cnt]++;
//for(i = 0; i <= 32; i++)
//printf("f[%d] = %d\n", i, f[i]);
}
LL all = (LL)1<<32;
int tp[33], a[33], b[33];
void solve(LL l, LL r) {
int i, j;
if(!l) {
memset(a, 0, sizeof(a));
gao(r, a);
//	printf("r = %d\n" , r);
//for(i = 0; i <= 3; i++)
//printf("a[%d] = %d\n", i, a[i]);
}
else if(l > 0) {
l--;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
gao(l, b); gao(r, a);
for(i = 0; i <= 32; i++)
a[i] -= b[i];
}
else if(l < 0 && r > 0) {
l--;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(tp, 0, sizeof(tp));
gao(r, a); gao(all+l, b); gao(all-1, tp);
for(i = 0; i <= 32; i++)
a[i] += (tp[i] - b[i]);
}
else if(l < 0 && r == 0) {
l--;
memset(a, 0, sizeof(a));
memset(tp, 0, sizeof(tp));
gao(all+l, tp); gao(all-1, a);
for(i = 0; i <= 32; i++)
a[i] -= tp[i];
a[0]++;
}
else {
l--;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
gao(all+l, b); gao(all+r, a);
for(i = 0; i <= 32; i++)
a[i] -= b[i];
}
}
int main() {
int cas;
LL l, r;
int i, k;
init();
cin >> cas;
while(cas--) {
cin >> l >> r >> k;
solve(l, r);
for(i = 0; i <= 32; i++) {
if(k < a[i]) break;
k -= a[i];
}
LL ans = -1;
LL ll = l;
while(l <= r) {
LL mid = (l + r) >> 1;
solve(ll, mid);
if(a[i] >= k) { ans = mid; r = mid-1; }
else l = mid+1;
}
cout << ans << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: