您的位置:首页 > 其它

[BZOJ 1853][Scoi2010]幸运数字:容斥原理

2017-05-31 20:54 483 查看
点击这里查看原题

因为最多有10位,所以最多有2+4+…+1024=2046个数,去掉存在倍数关系的数,对剩余的数做容斥

/*
User:Small
Language:C++
Problem No.:1853
*/
#include<bits/stdc++.h>
#define ll long long
#define inf 999999999
using namespace std;
int head,cnt,n;
bool vis[2100];
ll a[2100],b[2100];
ll ans,l,r;
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
void dfs(int now,ll sum,int cnt){
if(now==n+1){
if(cnt==0) return;
if(cnt&1) ans+=r/sum-(l-1)/sum;
else ans-=r/sum-(l-1)/sum;
return;
}
dfs(now+1,sum,cnt);
ll tmp=sum/gcd(sum,b[now]);
if((double)tmp*b[now]<=r){
dfs(now+1,tmp*b[now],cnt+1);
}
}
int main(){
freopen("data.in","r",stdin);//
while(cnt<2046){
a[++cnt]=a[head]*10+6;
a[++cnt]=a[head]*10+8;
head++;
}
for(int i=1;i<=cnt;i++)
if(!vis[i]){
b[++n]=a[i];
for(int j=i+1;j<=cnt;j++)
if(a[j]%a[i]==0) vis[j]=1;
}
for(int i=1;i<=n/2;i++) swap(b[i],b[n+1-i]);
scanf("%lld%lld",&l,&r);
dfs(1,1,0);
printf("%lld\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: