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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

HDU4669_Mutiples on a circle

發布時間:2023/12/19 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU4669_Mutiples on a circle 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目的意思是給你一些數字a[i](首位相連),現在要你選出一些連續的數字連續的每一位單獨地作為一個數位。現在問你有多少種選擇的方式使得選出的數字為k的一個倍數。

其實題目是很簡單的。由于k不大(200),總共的數字個數為50000,所以我們對于當前走到的每一個數字最多的狀態數目也只有50000*200個。

同時由于是循環的,我們可以使長度增倍,這樣就可以保證序列是循環的了。

不過注意,增倍后空間是開不下的,所以需要使用循環的滾動數組。

同時注意遞推的細節,還有有的a[i]不止一位數,不能直接取模。

?

#include <iostream> #include <cstdio> #include <cstring> #define maxn 50050 typedef long long ll; using namespace std;int a[2*maxn],f[2*maxn],n,m,k,tep,cur,w[2*maxn]; int s[maxn][205]; ll ans;void init_(int x) {for (int i=0; i<k; i++) s[x][i]=0; }int count(int x) {if (x<10) return 1;if (x<100) return 2;if (x<1000) return 3;return 4; }int get(int x) {if (x==1) return 10;if (x==2) return 100%k;if (x==3) return 1000%k;return 10000%k; }int power(int x,int y) {int tot=1;while (y){if (y&1) tot=(tot*x)%k;y>>=1;x=(x*x)%k;}return tot; }int main() {while (scanf("%d%d",&n,&k)!=EOF){ans=0;w[0]=0,f[0]=0;for (int i=1; i<=n; i++){scanf("%d",&a[i]);a[i+n]=a[i];w[i]=count(a[i]);w[i+n]=count(a[i+n]);}for (int i=1; i<=2*n; i++) f[i]=(f[i-1]*get(w[i])+a[i])%k;for (int i=1; i<=2*n; i++) w[i]+=w[i-1];for (int i=1; i<=n; i++){init_(i);s[i][a[i]%k]++;for (int j=0; j<k; j++) s[i][(get(w[i]-w[i-1])*j+a[i])%k]+=s[i-1][j]; }for (int i=n+1; i<=2*n; i++){int qq=i-n-1;if (qq==0) qq=n;init_(i-n);s[i-n][a[i]%k]++;for (int j=0; j<k; j++) s[i-n][(get(w[i]-w[i-1])*j+a[i])%k]+=s[qq][j];cur=(f[i-n-1]*power(10,w[i]-w[i-n-1]))%k;cur=((f[i]-cur)%k+k)%k; s[i-n][cur]--; ans+=s[i-n][0]; }printf("%I64d\n",ans);}return 0; }

?

轉載于:https://www.cnblogs.com/lochan/p/3446851.html

總結

以上是生活随笔為你收集整理的HDU4669_Mutiples on a circle的全部內容,希望文章能夠幫你解決所遇到的問題。

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