这是最早看懂题意的一题,状态转移,挺好想。。但是比赛时候,就是没有想到怎么去重,而且当时有些情况,也没注意到。
先预处理的dp[0]的情况,就是以p[0]为结尾的情况。之后D就行了,例如样例此位6,去重只要把642896 去掉就行了,dp[1][642896%m] --;注意这个值的更新。
突然发现。
1 #include2 #include 3 using namespace std; 4 #define LL __int64 5 int dp[50100][201]; 6 int p[50100]; 7 int d[50100]; 8 int po[200100]; 9 int fun(int x)10 {11 int i = 0;12 while(x)13 {14 i ++;15 x = x/10;16 }17 return i;18 }19 int main()20 {21 int n,m,i,j,sum,pre;22 while(scanf("%d%d",&n,&m)!=EOF)23 {24 for(i = 0;i <= n;i ++)25 {26 for(j = 0;j < m;j ++)27 dp[i][j] = 0;28 }29 po[0] = 1;30 for(i = 1;i <= 4*n;i ++)31 {32 po[i] = (po[i-1]*10)%m;33 }34 for(i = 0;i < n;i ++)35 {36 scanf("%d",&p[i]);37 d[i] = fun(p[i]);38 }39 p[n] = p[0];40 d[n] = d[0];41 sum = 0;42 pre = 0;43 for(i = n;i > 0;i --)44 {45 sum = (p[i]*po[pre] + sum)%m;46 pre += d[i];47 dp[0][sum] ++;48 }49 for(i = 1;i < n;i ++)50 {51 for(j = 0;j < m;j ++)52 {53 dp[i][(j*po[d[i]]+p[i])%m] += dp[i-1][j];54 }55 sum = (sum*po[d[i]] + p[i])%m;56 dp[i][sum] --;57 dp[i][p[i]%m] ++;58 sum = (sum - po[pre]*p[i])%m;59 if(sum < 0)60 sum += m;61 }62 LL ans = 0;63 for(i = 0;i < n;i ++)64 {65 ans += dp[i][0];66 }67 printf("%I64d\n",ans);68 }69 return 0;70 }