这是最早看懂题意的一题,状态转移,挺好想。。但是比赛时候,就是没有想到怎么去重,而且当时有些情况,也没注意到。
先预处理的dp[0]的情况,就是以p[0]为结尾的情况。之后D就行了,例如样例此位6,去重只要把642896 去掉就行了,dp[1][642896%m] --;注意这个值的更新。
突然发现。
1 #include <cstdio> 2 #include <cstring> 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 ",ans); 68 } 69 return 0; 70 }