题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4669

  题意:给一串数字连乘一个环,求连续的子串中组成的新的数字能被K整除的个数。

  首先容易想到用DP来解,f[i][j]表示以第 i 个数字结尾的所有前缀数中,余数为 j 的个数,那么Σ(f[i][0])就是答案。

  f[i][ j*10^len(num[i])+num[i] ]+=f[i][j]。

  但是这个要处理环的问题,所以我们要保证每次求的f[i][j]长度不能超过n。所以我们需要在转移f[i][j]的时候,要求出以当前数字num[i]开始的长度为n的数的余数r[i],那么在统计完f[i][0],后f[i][r[i]]--。其中r[i]还是好推的,r[i]=( r[i-1]-num[i]*10^(n-len[i]) )*10^len[i] + num[i] )%m = ( r[i-1]*10^len[i] -num[i]*10^s +num[i] )%m,其中s为总长度,len[i]为当前数字num[i]的位数。。

 //STATUS:C++_AC_203MS_1232KB
#include <functional>
#include <algorithm>
#include <iostream>
//#include <ext/rope>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,102400000")
//using namespace __gnu_cxx;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef __int64 LL;
typedef unsigned __int64 ULL;
//const
const int N=;
const int INF=0x3f3f3f3f;
//const LL MOD=1000000007,STA=8000010;
const LL LNF=1LL<<;
const double EPS=1e-;
const double OO=1e30;
const int dx[]={-,,,};
const int dy[]={,,,-};
const int day[]={,,,,,,,,,,,,};
//Daily Use ...
inline int sign(double x){return (x>EPS)-(x<-EPS);}
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
//End int f[][],len[N],num[N],ten[N<<];
int n,m; inline int getlen(int a)
{
int ret=;
while(a){
ret++;
a/=;
}
return ret;
} int main(){
// freopen("in.txt","r",stdin);
int i,j,p,t,r,s;
LL ans;
while(~scanf("%d%d",&n,&m))
{
s=;
for(i=;i<=n;i++){
scanf("%d",&num[i]);
s+=len[i]=getlen(num[i]);
num[i]%=m;
} ten[]=;
for(i=;i<=s;i++)ten[i]=(ten[i-]*)%m;
mem(f[],);
for(t=r=,i=n;i>;i--){
r=(num[i]*ten[t]+r)%m;
t+=len[i];
f[][r]++;
}
ans=f[][];f[][r]--;
for(i=,p=;i<n;i++){
mem(f[p=!p],);
for(j=;j<m;j++)
f[p][(j*ten[len[i]]+num[i])%m]+=f[!p][j];
f[p][num[i]]++;
ans+=(LL)f[p][];
r=(r*ten[len[i]]-num[i]*ten[s]+num[i])%m;
if(r<)r+=m;
f[p][r]--;
} printf("%I64d\n",ans);
}
return ;
}

HDU-4669 Mutiples on a circle 环形DP的更多相关文章

  1. HDU 4669 Mutiples on a circle 数位DP

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

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

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

  3. HDU 4669 Mutiples on a circle (DP , 统计)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:给出一个环,每个点是一个数字,取一个子串,使 ...

  4. 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 ...

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

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

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

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

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

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

  8. hdu 5025 Saving Tang Monk 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...

  9. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

随机推荐

  1. ue标签不见了,如何解决?

    小问题,但是很恶心...如下图: 解决方法: 右键点击[菜单栏]右边的空白处,选择advanced,默认是basic,这时菜单栏中的菜单条目会变多,然后选择[视图]---[视图/列表]---[打开文件 ...

  2. 修改jmeter jvm参数

    记录下常用的linux下 jmeter jvm参数修改,打开jmeter安装目录/bin/jmeter(非jmeter.sh) 1. 修改默认堆内存大小 #默认的 HEAP="-Xms512 ...

  3. *[topcoder]JumpFurther

    http://community.topcoder.com/stat?c=problem_statement&pm=12300&rd=15699 题意:有一个无限长的阶梯,i从1到N, ...

  4. Ubuntu中安装DiscuzX2

    http://blog.csdn.net/kevin_ysu/article/details/7452938 一.Apache的安装 Apache作为一个功能强大的Web程序,自然是架建Web服务器的 ...

  5. live555源码研究(十)------在编译过程中遇到的问题及解决方法

    一.编译testOnDemandRTSPServer.cpp. 在testProgs项目中,加入testOnDemandRTSPServer.cpp进行编译,编译类型是编译成exe文件,在编译过程中会 ...

  6. 转:Bitbucket使用方法

    一.软件及SSH keys: 由于我的Bitbucket账号的邮箱及用户名与Github相同,所以SSH Public Keys可以用Github的,登录Bitbucket,悬浮在用户名boliqua ...

  7. shorter concat [reverse longer]

    shorter concat [reverse longer] Description: Given 2 strings, a and b, return a string of the form:  ...

  8. HTML5学习(六)---------SVG 与Canvas

    参考教程:http://www.w3school.com.cn/html5/html_5_canvas_vs_svg.asp Canvas 和 SVG 都允许您在浏览器中创建图形,但是它们在根本上是不 ...

  9. MySQL open table

    背景:    MySQL经常会遇到Too many open files,MySQL上的open_files_limit和OS层面上设置的open file limit有什么关系? 源码中也会看到不同 ...

  10. ORACLE【1】:触发器详解

    转自:http://blog.csdn.net/indexman/article/details/8023740 ORACLE PL/SQL编程之八: 把触发器说透 本篇主要内容如下: 8.1 触发器 ...