[CF855E]Salazar Slytherin‘s Locket

Salazar Slytherin's Locket

题解

很水的一道数位dp。

在b进制下保证每个数的出现次数为偶,由于需要记录每个数出现次数的奇偶,而b\leq 10,很容易想到用状压来表示。

至于答案还是很常规的差分套路,用记忆化搜索来进行数位dp来求出小于等于某个数的满足条件数的个数。

dp_{i,j,k}i进制下,在第j位时状态为k时满足条件数的个数。

转移时还是用记忆化搜索进行,转移方程也很好想。

源码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const LL mo=1e9+7;
LL q,b,l[75],r[75],L,R,ans,dp[15][75][2205];
LL dfs(LL typ,int id,LL s,bool lim,bool pre){
	if(!id)return !s;LL up=lim?r[id]:b-1,sum=0;
	if(dp[typ][id][s]>=0&&!lim&&!pre)return dp[typ][id][s];
	for(int i=up;i>=0;i--){
		if(pre&&(!i)){sum+=dfs(typ,id-1,s,(i==r[id])&lim,1);continue;}
		sum+=dfs(typ,id-1,s^(1<<i),(i==r[id])&lim,0);
	}
	if(lim|pre)return sum;return dp[typ][id][s]=sum;
}
signed main(){
	memset(dp,-1,sizeof(dp));
	scanf("%lld",&q);
	while(q--){
		scanf("%lld %lld %lld",&b,&L,&R);L--;
		for(int i=1;i<=64;i++){
			l[i]=L%b;L/=b;
			r[i]=R%b;R/=b;
		}
		ans=dfs(b,64,0,1,1);
		for(int i=1;i<=64;i++)r[i]=l[i];
		printf("%lld\n",ans-dfs(b,64,0,1,1));
	}
	return 0;
}

谢谢!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值