转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

题意:给出一个环,每个点是一个数字,取一个子串,使得拼接起来的数字是K的倍数。

由于K不大,暂且不考虑环的话,那么dp[i][j]表示以i结尾的,模K为j的有多少个子串。

那么sigma (dp[i][0])便是不考虑环的答案。

考虑环的话,不知道别人怎么写的,我感觉我的写法不是很复杂。

环和情况1 和n肯定是必选的,那么便是一个前缀为后缀,一个后缀为前缀拼接而成。

所以枚举某个前缀,求出前缀模K,那么枚举后缀模K的值,通过之前已经预处理过的dp值,便可以求出有多少个后缀满足为K的倍数。

但是这样可能后缀和前缀重叠了,所以我们枚举前缀的同时,依次记录后缀不同模值的个数。

随着前缀的增长,这些后缀都是和前缀重叠的。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <vector>
#include <string>
#include <queue>
#include <cmath>
#include <algorithm>
#define lson step << 1
#define rson step << 1 | 1
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
const int N = 50005;
const int M = 205;
int n , k , a[N] ,l[N];
int dp[2][M] , prefix[N] , fac[N << 2] , suffix[N];
int cnt[M];
int cal (int x) {
int cnt = 0;
while (x) x /= 10 , cnt ++;
return cnt;
}
int main () {
#ifndef ONLINE_JUDGE
freopen ("input.txt" , "r" , stdin);
// freopen ("output.txt" , "w" , stdout);
#endif
while (scanf ("%d %d" , &n , &k) != EOF) {
fac[0] = 1;
for (int i = 1 ; i <= (n << 2) ; i ++)
fac[i] = fac[i - 1] * 10 % k;
for (int i = 1 ; i <= n ; i ++) {
scanf ("%d" , &a[i]);
l[i] = cal (a[i]);
}
for (int i = 0 ; i < 2 ; i ++) {
for (int j = 0 ; j < k ; j ++)
dp[i][j] = 0;
}
dp[1][a[1] % k] = 1;
LL ans = dp[1][0];
for (int i = 2 ; i <= n ; i ++) {
for (int j = 0 ; j < k ; j ++)
dp[i & 1][j] = 0;
dp[i & 1][a[i] % k] ++;
for (int j = 0 ; j < k ; j ++) {
dp[i & 1][(j * fac[l[i]] + a[i]) %k] += dp[(i - 1) & 1][j];
}
ans += dp[i & 1][0];
}
prefix[0] = 0;suffix[n + 1] = 0;
for (int i = 1 ; i <= n ; i ++) {
prefix[i] = (prefix[i - 1] * fac[l[i]] + a[i]) % k;
}
int len = 0;
for (int i = n ; i >= 1 ; i --) {
suffix[i] = (a[i] * fac[len] + suffix[i + 1]) % k;
len += l[i];
}
len = 0;
for (int i = 0 ; i < k ; i ++)
cnt[i] = 0;
for (int i = 1 ; i <= n ; i ++) {
cnt[suffix[i]] ++;
len += l[i];
int p = prefix[i];
for (int j = 0 ; j < k ; j ++) {
if ((j * fac[len] + p) % k) continue;
ans += dp[n & 1][j] - cnt[j];
}
}
printf ("%I64d\n" , ans);
}
return 0;
}

HDU 4669 Mutiples on a circle (DP , 统计)的更多相关文章

  1. HDU 4669 Mutiples on a circle (2013多校7 1004题)

    Mutiples on a circle Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Oth ...

  2. HDU 4669 Mutiples on a circle 数位DP

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4669 考察对取模的的理解深不深刻啊,当然还有状态的设计····设d[i][j]表示以第i个数结尾,余 ...

  3. HDU 4669 Mutiples on a circle(环状DP)

    题目链接 这是最早看懂题意的一题,状态转移,挺好想..但是比赛时候,就是没有想到怎么去重,而且当时有些情况,也没注意到. 先预处理的dp[0]的情况,就是以p[0]为结尾的情况.之后D就行了,例如样例 ...

  4. HDU 4669 Mutiples on a circle 不知道该归为哪一类。

    题意:给你N个珠宝和一个K,每个珠宝上面都有数字,这个珠宝做成项链,把珠宝上的数字拼起来如果可以整除掉K,那么久说这个数字为wonderful value,问你有多少种方案可以组成WONDERFUL ...

  5. HDU 4669 Mutiples on a circle 动态规划

    参考了官方题解给的方法: 对于处理循环,官方给了一种很巧妙的方法: #include <cstdio> #include <cstring> #include <cstd ...

  6. HDU 4665 Mutiples on a circle (圆环DP)

    题意 N个数的圆环上有多少种方案可以使得选出来的一段数是K的倍数(N<=50000, K<=200, a[i]<=1000). 思路 多校第七场1004.圆上的DP--大脑太简单处理 ...

  7. HDU 1024 Max Sum Plus Plus --- dp+滚动数组

    HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...

  8. HDU 1231 最大连续子序列 --- 入门DP

    HDU 1231 题目大意以及解题思路见: HDU 1003题解,此题和HDU 1003只是记录的信息不同,处理完全相同. /* HDU 1231 最大连续子序列 --- 入门DP */ #inclu ...

  9. hdu 4778 Gems Fight! 博弈+状态dp+搜索

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...

随机推荐

  1. RBAC - 基于角色的权限控制

    ThinkPHP中关于RBAC使用详解 自己的源码下载:百度网盘,thinkPHP文件夹下,RBAC文件夹. 重要的是,权限信息的写入函数等.在源码中能找到,Modules/Amin/Common/c ...

  2. BZOJ 3626: [LNOI2014]LCA( 树链剖分 + 离线 )

    说多了都是泪啊...调了这么久.. 离线可以搞 , 树链剖分就OK了... -------------------------------------------------------------- ...

  3. nginx前端负载,后端apache获取真实IP设置

    原文链接: nginx前端负载,后端apache获取真实IP设置 参考文献: 前端Nginx,后端Apache获取用户真实IP地址  按照第二种方法设置不成功! 网站最前端是nginx,做的PROXY ...

  4. [转]网络性能评估工具Iperf详解(可测丢包率)

    原文链接:安全运维之:网络性能评估工具Iperf详解:http://os.51cto.com/art/201410/454889.htm 参考博文:http://linoxide.com/monito ...

  5. Week11(11月18日)

    Part I:检查 =========================== 1.上堂课的练习效果. Part II:案例学习 =========================== MusicStor ...

  6. JavaScript 、ECMAScript、commonJS 发展历史 与标准化发展

    本文介绍下JavaScript和 ECMAScript的诞生及发展历史,以及标准化过程. 一.JavaScript诞生 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版. ...

  7. 正态分布(Normal distribution)又名高斯分布(Gaussian distribution)

    正态分布(Normal distribution)又名高斯分布(Gaussian distribution),是一个在数学.物理及project等领域都很重要的概率分布,在统计学的很多方面有着重大的影 ...

  8. Linux下arp用法

    [功能] 管理系统的arp缓存. [描述] 用来管理系统的arp缓存,常用的命令包括: arp: 显示所有的表项. arp  -d  address: 删除一个arp表项. arp  -s addre ...

  9. tweenanim动画

    1.视图 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:too ...

  10. Search a 2D Matrix【python】

    class Solution: # @param matrix, a list of lists of integers # @param target, an integer # @return a ...