转载请注明出处,谢谢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. ThinkPHP - 博客获取列表信息

    得到数据: Array ( [0] => Array ( [id] => 5 [name] => PHP [pid] => 0 [sort] => 1 [blog] =& ...

  2. iOS导航条渐变透明

    来源:HelloYeah 链接:http://www.jianshu.com/p/b8b70afeda81 下面这个界面有没有觉得很眼熟.打开你手里的App仔细观察,你会发现很多都有实现这个功能.比如 ...

  3. 432B - Football Kit

    解题思路: 暴力绝对TLE 一个队伍穿主场球衣的次数 = 这个队伍的客场球衣颜色与其他队主场球衣颜色起冲突的次数 + (n - 1) #include <stdio.h> #include ...

  4. m序列产生器

    扩频通讯中会用的到伪随机数列 —— m序列 代码中是5bit原始码 module m_generate ( clock , reset , m_code ); input clock ,reset ; ...

  5. CSipSimple最新版本号(二)--加入视频功能

    前面我们编译好了最新版本号的CSipSimple,并且測试已经能够打电话了.如今要把视频功能加上去. 不知道怎么编译的,能够看我的上一篇博文:CSipSimple最新版本号 我们先来看一下之前的项目是 ...

  6. C++部分术语(Terms)

    翻译自msdn,如有不妥当的地方,欢迎指正. 声明(Declaration):声明引入了一个名字以及其类型进入程序中,并没有定义一个相关的对象或者函数.然而,很多声明都作为定义使用.   定义(def ...

  7. 《Python爬虫学习系列教程》学习笔记

    http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己 ...

  8. 一、Nginx配置文件详解

    配置文件介绍 主要有两部分:分别是 main:主体部分 http{}:虚拟主机配置部分 配置指令主要以分号结尾:配置语法:directive value1 [value2 ....] 支持使用的变量 ...

  9. 新浪微博中tableview中头部信息

    摘自http://www.cnblogs.com/gcb999/p/3151665.html #import <UIKit/UIKit.h> @class User; @protocol ...

  10. Rabbit.Rpc

    .NET轻量级RPC框架:Rabbit.Rpc 最近准备写一个.NET的管理平台应用在公司,由于存在大量的Client => Server,Server => Client的请求需求在加上 ...