dfs版容斥原理+剪枝——bzoj1853
Posted zsben991126
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dfs版容斥原理+剪枝——bzoj1853相关的知识,希望对你有一定的参考价值。
学了一种爆搜版+剪枝的容斥方法,即类似数位dp时按位进行容斥,同时需要在搜索过程中进行剪枝
/* 容斥原理,先在打出的表里筛掉所有倍数,然后用容斥原理+1个的倍数-2个lcm的倍数+3个lcm的倍数... 注意剪枝,判断防止爆long long */ #include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 200005 ll l,r,ans; ll a[maxn],m,b[maxn],n; void init(ll x) if(x>r)return; a[++m]=x; init(x*10+6); init(x*10+8); void dfs(int pos,int num,ll now) if(pos>n) if(num%2) ans+=r/now-(l-1)/now; else if(num)ans-=r/now-(l-1)/now; return; dfs(pos+1,num,now);//不取第pos位 ll tmp=now/__gcd(b[pos],now);//防止爆ll if((double)b[pos]*tmp<=(double)r) dfs(pos+1,num+1,b[pos]*tmp); int vis[maxn]; int main() cin>>l>>r; init(6);init(8); sort(a+1,a+1+m);//排成有序数列 for(int i=1;i<=m;i++) if(vis[i]==0) for(int j=i+1;j<=m;j++) if(a[j]%a[i]==0) vis[j]=1; for(int i=m;i>=1;i--) if(!vis[i])b[++n]=a[i]; dfs(1,0,1); cout<<ans<<endl;
以上是关于dfs版容斥原理+剪枝——bzoj1853的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ-1853: [Scoi2010]幸运数字 (容斥原理)
[bzoj1853][Scoi2010][幸运数字] (容斥原理)