转载请注明出处,谢谢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. java的数据类型,几个java小程序

    1:求圆的面积 还好看了c++,不然直接看这课件还真是看不懂……加油吧 要从键盘读入数据可以用Scanner类的nextlnt()或者nextDouble()方法,首先创建Scanner类的一个实例, ...

  2. Week3(9月23日):例子更Powerful更完整了,哇咔咔

    Part I:提问  =========================== 1.控制器中动作方法的返回类型有哪些? 2.如果控制器代码如下,请问浏览器中如何输入什么路由访问? public clas ...

  3. QML基础(六篇文章)

    http://www.cnblogs.com/hicjiajia/category/350988.html

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

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

  5. JQuery中两个ul标签的li互相移动实现方法

    这篇文章主要介绍了JQuery中两个ul标签的li互相移动实现方法,可实现ul标签中li标签内容相互替换的技巧,涉及jQuery操作页面元素的相关技巧,需要的朋友可以参考下 本文实例讲述了JQuery ...

  6. csharp .net vb 复制图像

    .NET Compact Framework 不支持 Image.Clone 方法,可是仍能够复制图像和图像的某些部分.以下的演示例子演示怎样运行以下操作: 定义一个方法以创建位图. 定义一个重载方法 ...

  7. 提高mysql查询效率的六种方法

    1,表设计一定要优化,冗余数据最少,少用连接查询.如果在实际应用中,使用了极其复杂的连接,子查询,则数据表的设计得要重新考虑了. 2,尽量用char而不是varchar,因为固定长度得string用起 ...

  8. HDU SPFA算法 Invitation Cards

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1535 分析: 题意:求1点到其它点的最短距离之和+其它点到1点的最短距离之和 前面一部分直接用SPFA ...

  9. 采用sharedPreference保存数据

    1.sharedPreference保存数据 package com.example.login.service; import java.io.BufferedReader; import java ...

  10. java--join方法

    package MyTest; class TestDemo implements Runnable { public void run() { int i = 0; for (int j = 0; ...