日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P2567 [SCOI2010]幸运数字

發布時間:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P2567 [SCOI2010]幸运数字 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

P2567 [SCOI2010]幸運數字

題意:

我們規定只含6或8的數字為幸運號碼,而幸運號碼的倍數我們也認為是幸運號碼,問[l,r]中有多少個幸運號碼?

題解:

第一反應是數位dp,但其實不是,我們可以打表觀察下,幸運數字其實很少,也就1000多個,所有我門全可以用容斥來去做。
先去搞定所有范圍內的合法數字,然后直接容斥
對于有個幸運數字X,在[L,R]中X的倍數的個數,就是R/X-(L-1)/X,但是兩個幸運數字有可能會存在交集,即重復計算,所有要用到容斥,選一個幸運數字-選兩個幸運數字的lcm+選3個幸運數字的lcm-…(容斥原理)
但是直接這樣做也會超時,需要剪枝:

  • 對于兩個幸運數字a,b,如果b%a==0,那么如果b/x就一定包含了a/x,因此這樣的b沒有必要,也就是幸運數字的倍數我們就不用管了,這樣就剩下943個幸運號碼
  • 如果當然的lcm大于r,就沒必要繼續搜索了,因為已經超出范圍
  • 我們將幸運數字從大到小排序,可以使得lcm更快的超越上屆r
  • 代碼:

    #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]幸运数字的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。