您的位置:首页 > 其它

bzoj 2393 Cirno的完美算数教室(容斥原理+搜索)

2016-03-30 11:37 405 查看
【题意】

定义C数为只包含数字2和9的数,求[L,R]内能被C数整除的个数。

【思路】

Dfs预处理出C数,并去除其中倍数的情况。

Dfs搜索出现情况,奇数加,偶数减,当数值大于R时剪枝。

【代码】

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long ll;
const int N = 2e3+10;

ll a
,b
,vis
,ans,tot,n,L,R;

void get_pre(int num)
{
if(num>R) return ;
if(num) a[++tot]=num;
get_pre(num*10+2);
get_pre(num*10+9);
}
ll gcd(ll a,ll b)
{
return b==0? a:gcd(b,a%b);
}
void dfs(int cur,int cnt,ll lcm)
{
if(cur==n+1) {
if(cnt&1) ans+=R/lcm-(L-1)/lcm;
else if(cnt) ans-=R/lcm-(L-1)/lcm;
return ;
}
dfs(cur+1,cnt,lcm);
ll val=lcm*a[cur]/(gcd(lcm,a[cur]));
if(val<=R) dfs(cur+1,cnt+1,val);
}

int main()
{
scanf("%lld%lld",&L,&R);
get_pre(0);
sort(a+1,a+tot+1);
for(int i=1;i<=tot;i++)
if(!vis[i]) {
b[++n]=a[i];
for(int j=i+1;j<=tot;j++)
if(a[j]%a[i]==0) vis[j]=1;
}
for(int i=1;i<=n;i++)
a[i]=b[n-i+1];
dfs(1,0,1);
printf("%lld\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: