HDU-4669 Mutiples on a circle 环形DP
2013-08-14 17:18
309 查看
题目链接: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]的位数。。
题意:给一串数字连乘一个环,求连续的子串中组成的新的数字能被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=50010; const int INF=0x3f3f3f3f; //const LL MOD=1000000007,STA=8000010; const LL LNF=1LL<<55; const double EPS=1e-9; const double OO=1e30; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //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[2][205],len ,num ,ten[N<<2]; int n,m; inline int getlen(int a) { int ret=0; while(a){ ret++; a/=10; } 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=0; for(i=1;i<=n;i++){ scanf("%d",&num[i]); s+=len[i]=getlen(num[i]); num[i]%=m; } ten[0]=1; for(i=1;i<=s;i++)ten[i]=(ten[i-1]*10)%m; mem(f[0],0); for(t=r=0,i=n;i>0;i--){ r=(num[i]*ten[t]+r)%m; t+=len[i]; f[0][r]++; } ans=f[0][0];f[0][r]--; for(i=1,p=0;i<n;i++){ mem(f[p=!p],0); for(j=0;j<m;j++) f[p][(j*ten[len[i]]+num[i])%m]+=f[!p][j]; f[p][num[i]]++; ans+=(LL)f[p][0]; r=(r*ten[len[i]]-num[i]*ten[s]+num[i])%m; if(r<0)r+=m; f[p][r]--; } printf("%I64d\n",ans); } return 0; }
相关文章推荐
- HDU 4669 Mutiples on a circle (环形数列DP)byPlato
- 2013 多校第七场 hdu 4669 Mutiples on a circle(DP,环)
- hdu 4669 Mutiples on a circle(按位DP)
- HDU 4669 Mutiples on a circle(DP)
- HDU 4669 Mutiples on a circle 数位DP
- HDU 4669 Mutiples on a circle (DP , 统计)
- HDU 4669 Mutiples on a circle(环状DP)
- HDU 4669 Mutiples on a circle (DP , 统计)
- HDU 4665 Mutiples on a circle (圆环DP)
- HDU 4665 Mutiples on a circle (圆环DP)
- HDU 4669 Mutiples on a circle (2013多校7 1004题)
- hdu 4669 Mutiples on a circle(高效)
- HDU 4669 Mutiples on a circle 不知道该归为哪一类。
- HDU 4669 Mutiples on a circle 解题报告
- hdu 4669 Mutiples on a circle
- HDU - 4669 Mutiples on a circle
- HDU 4669 Mutiples on a circle (2013多校联合7 1004)
- hdu 4669——Mutiples on a circle
- HDU 4669 Mutiples on a circle 动态规划
- HDOJ 4669 Mutiples on a circle