×

第十五篇:P6218

题解补完计划:第十五篇

原题题面

简单题,显然,我们可以将其转化为 \(r\) 时候的答案减去 \(l\) 时候的答案,剩下的就是数位 DP(为什么数位 DP 不叫记忆化搜索?

#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define intl long long
#define For(i,a,b) for(intl i=a;i<=b;i++)
#define deo(i,a,b) for(intl i=a;i>=b;i--)
intl read() {
	intl x=0,k=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch == '-') k=-1;ch=getchar();}
	while(isdigit(ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*k;
}
intl cnt[N], n, r, l, dp[2][2][64][64];
intl dfs(intl pos, intl vis,intl up,intl diff) {
//	cout << pos << " " << diff << endl;
	if(!pos) return diff >= 32;
	if(dp[vis][up][pos][diff] != -1) return dp[vis][up][pos][diff];
	intl lim = up?cnt[pos]:1, res = 0;
	For(i,0,lim) res += dfs(pos-1, vis&(i == 0), up&(i == lim), diff + (!i?(vis?0:1):-1));
	return dp[vis][up][pos][diff] = res;
}
intl get(intl x) {
//	cout << "--------------------------------------\n";
	For(i,0,64) cnt[i] = 0;
	intl tot = 0;
	while(x) cnt[++tot] = x&1, x >>= 1;
//	For(i,0,64) cout << cnt[i] << " \n"[i == 64];
	return dfs(tot,1,1,32);
}
int main() {
	memset(dp,-1, sizeof dp);
	l = read(), r = read();
	printf("%lld\n", get(r) - get(l-1));
	return 0;
}


posted @ 2026-10-05 20:32  shiori123  阅读(4)  评论(0)    收藏  举报