bzoj 2393 Cirno的完美算数教室(容斥原理+搜索)
【题意】
定义C数为只包含数字2和9的数,求[L,R]内能被C数整除的个数。
【思路】
Dfs预处理出C数,并去除其中倍数的情况。
Dfs搜索出现情况,奇数加,偶数减,当数值大于R时剪枝。
【代码】
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 typedef long long ll; 7 const int N = 2e3+10; 8 9 ll a[N],b[N],vis[N],ans,tot,n,L,R; 10 11 void get_pre(int num) 12 { 13 if(num>R) return ; 14 if(num) a[++tot]=num; 15 get_pre(num*10+2); 16 get_pre(num*10+9); 17 } 18 ll gcd(ll a,ll b) 19 { 20 return b==0? a:gcd(b,a%b); 21 } 22 void dfs(int cur,int cnt,ll lcm) 23 { 24 if(cur==n+1) { 25 if(cnt&1) ans+=R/lcm-(L-1)/lcm; 26 else if(cnt) ans-=R/lcm-(L-1)/lcm; 27 return ; 28 } 29 dfs(cur+1,cnt,lcm); 30 ll val=lcm*a[cur]/(gcd(lcm,a[cur])); 31 if(val<=R) dfs(cur+1,cnt+1,val); 32 } 33 34 int main() 35 { 36 scanf("%lld%lld",&L,&R); 37 get_pre(0); 38 sort(a+1,a+tot+1); 39 for(int i=1;i<=tot;i++) 40 if(!vis[i]) { 41 b[++n]=a[i]; 42 for(int j=i+1;j<=tot;j++) 43 if(a[j]%a[i]==0) vis[j]=1; 44 } 45 for(int i=1;i<=n;i++) 46 a[i]=b[n-i+1]; 47 dfs(1,0,1); 48 printf("%lld\n",ans); 49 return 0; 50 }
posted on 2016-03-30 11:37 hahalidaxin 阅读(422) 评论(0) 编辑 收藏 举报