HDU 4669 Mutiples on a circle (DP , 统计)
转载请注明出处,谢谢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 , 统计)的更多相关文章
- 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 ...
- HDU 4669 Mutiples on a circle 数位DP
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4669 考察对取模的的理解深不深刻啊,当然还有状态的设计····设d[i][j]表示以第i个数结尾,余 ...
- HDU 4669 Mutiples on a circle(环状DP)
题目链接 这是最早看懂题意的一题,状态转移,挺好想..但是比赛时候,就是没有想到怎么去重,而且当时有些情况,也没注意到. 先预处理的dp[0]的情况,就是以p[0]为结尾的情况.之后D就行了,例如样例 ...
- HDU 4669 Mutiples on a circle 不知道该归为哪一类。
题意:给你N个珠宝和一个K,每个珠宝上面都有数字,这个珠宝做成项链,把珠宝上的数字拼起来如果可以整除掉K,那么久说这个数字为wonderful value,问你有多少种方案可以组成WONDERFUL ...
- HDU 4669 Mutiples on a circle 动态规划
参考了官方题解给的方法: 对于处理循环,官方给了一种很巧妙的方法: #include <cstdio> #include <cstring> #include <cstd ...
- HDU 4665 Mutiples on a circle (圆环DP)
题意 N个数的圆环上有多少种方案可以使得选出来的一段数是K的倍数(N<=50000, K<=200, a[i]<=1000). 思路 多校第七场1004.圆上的DP--大脑太简单处理 ...
- HDU 1024 Max Sum Plus Plus --- dp+滚动数组
HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...
- HDU 1231 最大连续子序列 --- 入门DP
HDU 1231 题目大意以及解题思路见: HDU 1003题解,此题和HDU 1003只是记录的信息不同,处理完全相同. /* HDU 1231 最大连续子序列 --- 入门DP */ #inclu ...
- hdu 4778 Gems Fight! 博弈+状态dp+搜索
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...
随机推荐
- RBAC - 基于角色的权限控制
ThinkPHP中关于RBAC使用详解 自己的源码下载:百度网盘,thinkPHP文件夹下,RBAC文件夹. 重要的是,权限信息的写入函数等.在源码中能找到,Modules/Amin/Common/c ...
- BZOJ 3626: [LNOI2014]LCA( 树链剖分 + 离线 )
说多了都是泪啊...调了这么久.. 离线可以搞 , 树链剖分就OK了... -------------------------------------------------------------- ...
- nginx前端负载,后端apache获取真实IP设置
原文链接: nginx前端负载,后端apache获取真实IP设置 参考文献: 前端Nginx,后端Apache获取用户真实IP地址 按照第二种方法设置不成功! 网站最前端是nginx,做的PROXY ...
- [转]网络性能评估工具Iperf详解(可测丢包率)
原文链接:安全运维之:网络性能评估工具Iperf详解:http://os.51cto.com/art/201410/454889.htm 参考博文:http://linoxide.com/monito ...
- Week11(11月18日)
Part I:检查 =========================== 1.上堂课的练习效果. Part II:案例学习 =========================== MusicStor ...
- JavaScript 、ECMAScript、commonJS 发展历史 与标准化发展
本文介绍下JavaScript和 ECMAScript的诞生及发展历史,以及标准化过程. 一.JavaScript诞生 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版. ...
- 正态分布(Normal distribution)又名高斯分布(Gaussian distribution)
正态分布(Normal distribution)又名高斯分布(Gaussian distribution),是一个在数学.物理及project等领域都很重要的概率分布,在统计学的很多方面有着重大的影 ...
- Linux下arp用法
[功能] 管理系统的arp缓存. [描述] 用来管理系统的arp缓存,常用的命令包括: arp: 显示所有的表项. arp -d address: 删除一个arp表项. arp -s addre ...
- tweenanim动画
1.视图 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:too ...
- Search a 2D Matrix【python】
class Solution: # @param matrix, a list of lists of integers # @param target, an integer # @return a ...