http://acm.hdu.edu.cn/showproblem.php?pid=4669
这题各种错误都来了一遍 预处理一下第一个数作为尾数与相邻前面的数组成的数的余数 然后再与后面的结合求余数
9 6 4 2 8
因为是个环 可以 9 6 4 2 8 9 6 4 2 8 组合 不过 又不能超N
所以先预处理 89 289 4289 64289 的余数 再与后面的组合 删除重复的
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 50005
#define LL __int64
int dp[N][];
int b[N],di[N],pp[N*];
int digit(int x)
{
int i=;
while(x)
{
i++;
x/=;
}
return i;
}
int main()
{
int i,k,n,r,j;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(i = ; i <= n ;i++)
for(j = ; j < k ; j++)
dp[i][j] = ;
for(i = ; i <= n ; i++)
{
scanf("%d",&b[i]);
di[i] = digit(b[i]);
}
pp[] = ;
for(i = ; i <= n* ; i++)
pp[i] = (pp[i-]*)%k;
int pre = ;
b[n+] = b[];
di[n+] = di[];
r = ;
for(i = n+ ; i > ; i--)
{
r = (b[i]*pp[pre]+r)%k;
pre+=di[i];
dp[][r]++;
}
int rr = r;
for(i = ; i <= n ; i++)
{
for(r = ; r < k ; r++)
{
int o = (r*pp[di[i]]+b[i])%k;
dp[i][o] += dp[i-][r];
}
rr = (rr*pp[di[i]]+b[i])%k;
dp[i][rr]--;
dp[i][b[i]%k]++;
rr = (rr-pp[pre]*b[i]+k)%k;
if(rr<) rr+=k;
}
LL maxz=;
for(i = ; i <= n ; i++)
{
maxz+=dp[i][];
}
printf("%I64d\n",maxz);
}
return ;
}