标签:
【数据范围】
对于30%的数据,保证1 < =a < =b < =1000000
对于100%的数据,保证1 < =a < =b < =10000000000
容斥原理 爆搜 剪枝
先预处理出baka数(幸运数),再去一下重(删除能被其他baka数整除的)
容斥之前有一个结论:
N内a或b的倍数的个数=N/a+N/b-N/lcm(a,b),即:a在N以内的倍数+b在N以内的倍数-a和b两个在N以内的相同的倍数(所以从 最小公倍数 开始)
然后就可以容斥,爆搜+剪枝 就可以A了 一个最行之有效的剪枝就是一开始所说的去重 也可以吧超过R的部分直接忽略
By The Way:baka数可以正常A,幸运数那题,需要改成unsigned long long,不然会TLE (可是本机明明跑的一样快)
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; #define maxn 100100 unsigned long long L,R; int top,Top; unsigned long long stack[maxn],ans; void Prework(long long x) { if (x<=R) stack[++top]=x; else return; Prework(x*10+6); Prework(x*10+8); } bool cmp(long long a,long long b) {return a>b;} long long gcd(long long a,long long b) {if (!b) return a; return gcd(b,a%b);} void DFS(int dep,int t,long long x) { if (dep==Top+1) { if (t%2) ans+=R/x-(L-1)/x; else if (t) ans-=R/x-(L-1)/x; return; } DFS(dep+1,t,x); if (stack[dep]*x/gcd(stack[dep],x)<=R) DFS(dep+1,t+1,stack[dep]*x/gcd(stack[dep],x)); } int main() { // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); scanf("%lld%lld",&L,&R); Prework(6); Prework(8); sort(stack+1,stack+top+1); // for (int i=1; i<=top; i++) printf("%d ",stack[i]); puts(""); for (int i=1; i<=top; i++) if (stack[i]) { for (int j=i+1; j<=top; j++) if (stack[j]%stack[i]==0) stack[j]=0; stack[++Top]=stack[i]; } sort(stack+1,stack+Top+1,cmp); // for (int i=1; i<=Top; i++) printf("%d ",stack[i]); puts(""); DFS(1,0,1); printf("%lld\n",ans); return 0; }
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; #define maxn 10010 int L,R,top,Top; long long stack[maxn],ans; void Prework(long long x) { if (x<=R) stack[++top]=x; else return; Prework(x*10+2); Prework(x*10+9); } bool cmp(long long a,long long b) {return a>b;} long long gcd(long long a,long long b) {if (!b) return a; return gcd(b,a%b);} void DFS(int dep,int t,long long x) { if (dep==Top+1) { if (t%2) ans+=R/x-(L-1)/x; else if (t) ans-=R/x-(L-1)/x; return; } DFS(dep+1,t,x); if (stack[dep]*x/gcd(stack[dep],x)<=(long long)R) DFS(dep+1,t+1,stack[dep]*x/gcd(stack[dep],x)); } int main() { scanf("%d%d",&L,&R); Prework(2); Prework(9); sort(stack+1,stack+top+1); // for (int i=1; i<=top; i++) printf("%d ",stack[i]); puts(""); for (int i=1; i<=top; i++) if (stack[i]) { for (int j=i+1; j<=top; j++) if (stack[j]%stack[i]==0) stack[j]=0; stack[++Top]=stack[i]; } sort(stack+1,stack+Top+1,cmp); // for (int i=1; i<=Top; i++) printf("%d ",stack[i]); puts(""); DFS(1,0,1); printf("%lld\n",ans); return 0; }
去CodeVS群问了波..感觉弱智+10
【BZOJ-1853&2393】幸运数字&Cirno的完美算数教室 容斥原理 + 爆搜 + 剪枝
标签:
原文地址:http://www.cnblogs.com/DaD3zZ-Beyonder/p/5473967.html