标签:答案 inpu pac 并且 输入数据 register void space 数字
【数据范围】
对于30%的数据,保证1 < =a < =b < =1000000
对于100%的数据,保证1 < =a < =b < =10000000000
正解:搜索+容斥原理。
首先把所有幸运数搜索出来,最多只会有$2046$个。
然后我们考虑容斥原理,即暴力枚举每个数用不用,然后加减一下贡献即可。
但是极限数据跑不过,我们加两个剪枝。
首先我们把所有幸运数从大到小搜索,这样留给后面的状态就会变少。
然后我们把是一个幸运数数的倍数的幸运数去掉,可以发现这是不会影响答案的,并且可以减少状态。
然后注意求$lcm$可能会爆$long \ long$,我们使用$double$即可。这样我们就能通过此题了。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 6 using namespace std; 7 8 ll st[5010],ss[5050],vis[5050],tp,top,ans,a,b; 9 10 il ll cmp(const ll &a,const ll &b){ return a>b; } 11 12 il ll gcd(RG ll a,RG ll b){ return b ? gcd(b,a%b) : a; } 13 14 il double lcm(RG ll a,RG ll b){ return 1.0*a/gcd(a,b)*b; } 15 16 il void dfs0(RG ll x,RG ll tot){ 17 if (tot>b) return; if (tot) st[++top]=tot; 18 dfs0(x+1,tot*10+6),dfs0(x+1,tot*10+8); return; 19 } 20 21 il void dfs(RG ll x,RG ll tot,RG ll op){ 22 if (x>top){ 23 if (tot==1) return; 24 if (op) ans+=b/tot-(a-1)/tot; 25 else ans-=b/tot-(a-1)/tot; 26 return; 27 } 28 dfs(x+1,tot,op); RG double res=lcm(tot,st[x]); 29 if (res>b) return; dfs(x+1,res,op^1); return; 30 } 31 32 int main(){ 33 #ifndef ONLINE_JUDGE 34 freopen("number.in","r",stdin); 35 freopen("number.out","w",stdout); 36 #endif 37 cin>>a>>b,dfs0(1,0); 38 for (RG int i=1;i<top;++i) 39 for (RG int j=i+1;j<=top;++j) 40 if (st[i]%st[j]==0) vis[i]=1; 41 else if (st[j]%st[i]==0) vis[j]=1; 42 for (RG int i=1;i<=top;++i) if (!vis[i]) ss[++tp]=st[i]; 43 for (RG int i=1;i<=tp;++i) st[i]=ss[i]; top=tp; 44 sort(st+1,st+top+1,cmp),dfs(1,1,0),cout<<ans; return 0; 45 }
标签:答案 inpu pac 并且 输入数据 register void space 数字
原文地址:http://www.cnblogs.com/wfj2048/p/7693605.html