P2567 [SCOI2010]幸运数字
生活随笔
收集整理的這篇文章主要介紹了
P2567 [SCOI2010]幸运数字
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
P2567 [SCOI2010]幸運數字
題意:
我們規定只含6或8的數字為幸運號碼,而幸運號碼的倍數我們也認為是幸運號碼,問[l,r]中有多少個幸運號碼?
題解:
第一反應是數位dp,但其實不是,我們可以打表觀察下,幸運數字其實很少,也就1000多個,所有我門全可以用容斥來去做。
先去搞定所有范圍內的合法數字,然后直接容斥
對于有個幸運數字X,在[L,R]中X的倍數的個數,就是R/X-(L-1)/X,但是兩個幸運數字有可能會存在交集,即重復計算,所有要用到容斥,選一個幸運數字-選兩個幸運數字的lcm+選3個幸運數字的lcm-…(容斥原理)
但是直接這樣做也會超時,需要剪枝:
代碼:
#include<bits/stdc++.h> #define debug(a,b) printf("%s = %d\n",a,b); using namespace std; typedef long long ll; typedef pair<int, int> PII; clock_t startTime, endTime; //Fe~Jozky const ll INF_ll=1e18; const int INF_int=0x3f3f3f3f; inline ll read(){ll s=0,w=1ll;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1ll;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10ll+((ch-'0')*1ll),ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w; } void rd_test(){#ifdef ONLINE_JUDGE#elsestartTime = clock(); //計時開始freopen("2567.in","r",stdin);#endif } void Time_test(){#ifdef ONLINE_JUDGE#elseendTime = clock(); //計時結束printf("\n運行時間為:%lfs\n",(double)(endTime - startTime) / CLOCKS_PER_SEC);#endif } const int N=20005; const int dig1=6; const int dig2=8; ll l,r,a[N],ans,tot; inline bool cmp(ll x,ll y){return x>y;} void init(ll x){if(x>r)return;if(x>0)a[++tot]=x;init(x*10+dig1);init(x*10+dig2); } ll gcd(ll x,ll y){return y?gcd(y,x%y):x; } void dfs(int now,int sum,ll k){if(now>tot){if(!sum)return;if(sum&1)ans+=(r/k-(l-1)/k);else ans-=(r/k-(l-1)/k);return;}dfs(now+1,sum,k);if((double long)k/gcd(k,a[now])<=(double long)r/a[now])dfs(now+1,sum+1,k*a[now]/gcd(k,a[now])); } int main(){scanf("%lld%lld",&l,&r);init(0);sort(a+1,a+tot+1,cmp);int tmp=0;for(int i=1;i<=tot;i++){for(int j=i+1;j<=tot&&a[i];j++){if(!a[j])continue;if(a[i]%a[j]==0)a[i]=0;}if(a[i])a[++tmp]=a[i];}tot=tmp;dfs(1,0,1);printf("%lld\n",ans);return 0; }總結
以上是生活随笔為你收集整理的P2567 [SCOI2010]幸运数字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: xay loves trees
- 下一篇: P2571 [SCOI2010]传送带