bzoj 1799: [Ahoi2009]self 类似的分布 解读
【原标题】
1799: [Ahoi2009]self 同类分布
Time Limit: 50 Sec Memory Limit: 64 MB id=1799" style="color:blue; text-decoration:none">Submit id=1799" style="color:blue; text-decoration:none">Status
Submit: 554 Solved: 194
[
Description
Input
Output
Sample Input
Sample Output
HINT
【约束条件】1 ≤ a ≤ b ≤ 10^18
Source
【分析】肯定是数位DP。只是望着50s的时限我大笑:这么宽?
于是匆匆整理了思路。
最多时18个9。也就是和最大值是162。首先我要先枚举和P。
状态怎么表示呢?哦。f[i][j][k][sum]表示到第i位。首位是j,眼下总和是sum,且眼下模P的答案是K。推起来简单。就是统计的时候还是得一位一位的来,略麻烦。
可是写完后。我发现例子时过了,可连例子都跑得飞慢!。。
计算效率:162*18*10*162*162。咦?怎么算都是超时的!!。
【代码1】
#include<cstdio>
#include<cstring>
#include<cmath>
#define D 19
#define S 163
#define G 10
using namespace std;
typedef long long LL;
LL f[D][G][S][S],A,B,M[D][S];
LL PRE()
{
int a[D]={0},cnta=0;LL ansa=0;
for (;A;A/=10ll) a[++cnta]=A%10;
int b[D]={0},cntb=0;LL ansb=0;
for (;B;B/=10ll) b[++cntb]=B%10;
for (int P=1;P<=162;P++)
{
memset(f,0,sizeof(f));
for (int i=0;i<10;i++) f[1][i][i%P][i]=1ll;
for (int i=1;i<cntb;i++)
for (int j=0;j<=9;j++)
for (int k=0;k<P;k++)
for (int sum=0;sum<=P;sum++)
if (f[i][j][k][sum])
{
for (int now=0;now<=9;now++)
f[i+1][now][(k+now*M[i][P])%P][sum+now]+=f[i][j][k][sum];
}
LL ta=ansa,tb=ansb;
int s=0,d=0,now=0;
for (int i=cnta;i;i--)
{
for (int j=(i==1);j<a[i];j++) ansa+=f[i][j][now][P-d];
s=(s+a[i])*10%P;d+=a[i];now=(P-s)*(P!=s);
}
s=0;d=0;now=0;
for (int i=cntb;i;i--)
{
for (int j=(i==1);j<b[i];j++) ansb+=f[i][j][now][P-d];
s=(s+b[i])*10%P;d+=b[i];now=(P-s)*(P!=s);
}
}
if (!ansa) ansa--;
return ansb-ansa;
}
int main()
{
scanf("%lld%lld",&A,&B);A--;
M[0][1]=0;for (int j=2;j<=162;j++) M[0][j]=1;
for (int i=1;i<=18;i++)
for (int j=1;j<=162;j++)
M[i][j]=M[i-1][j]*10ll%j;
printf("%lld",PRE());
return 0;
}
于是无节操的去看题解。
有一位P党的大神是按位去枚举sum的。效率非常高。
于是就。
。
。嘿嘿。
。。
赶紧借鉴一下。
然后发现空间上过不去。。。。
上面内存限制64M(当然BZOJ上超一点点没什么事),我68M!
于是開始压内存。把无用的全删除了——66M!
怎么办?打了一个非常小的点(事实上也不算是打点。仅仅是把sum=162的这样的情况去掉)
65M多!
!
还是卡只是去!
!
气死了。就用数组自然溢出吧!咦?居然过了。!
【代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define D 19
#define S 160 //原来是163
using namespace std;
typedef long long LL;
LL f1[S-1][S][S-1],f2[S-1][S][S-1];LL A,B;
LL PRE(LL A)
{
int a[D]={0},cnt=0,y,i,j,k,l,z,sum=0;LL ans=0,x=A,mul,now;
if (!A) return 0;
for (;A;A/=10ll) a[++cnt]=A%10,sum+=a[cnt];
for (i=1;i<=cnt/2;i++) swap(a[i],a[cnt-i+1]);
memset(f1,0,sizeof(f1));
for (i=1;i<S;i++) f1[0][i][0]=1ll;
if (x%sum==0) ans++;mul=1ll;
for (i=0;i<cnt;i++)
{
x/=10ll;mul*=10ll;now=x*mul;sum-=a[cnt-i];
for (z=0;z<a[cnt-i];z++)
{
for (j=sum+z+(sum+z==0);j<=sum+z+i*9;j++)
y=(now%j)?j-now%j:0,ans+=f1[j-sum-z][j][y];
now+=mul/10;
}
memcpy(f2,f1,sizeof(f1));
memset(f1,0,sizeof(f1));
for (j=0;j<=i*9;j++)
for (k=j;k<S;k++)
for (l=0;l<k;l++)
for (z=0;z<=9;z++)
f1[j+z][k][(l*10+z)%k]+=f2[j][k][l];
}
return ans;
}
int main()
{
scanf("%lld%lld",&A,&B); if (B>=999999999999999999ll) B=999999999999999998ll,printf("%lld",PRE(B)-PRE(A-1)+1);
else printf("%lld",PRE(B)-PRE(A-1));
return 0;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
bzoj 1799: [Ahoi2009]self 类似的分布 解读的更多相关文章
- bzoj 1799: [Ahoi2009]self 同类分布 数位dp
1799: [Ahoi2009]self 同类分布 Time Limit: 50 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Descripti ...
- BZOJ 1799 - [AHOI2009]self 同类分布 - 枚举 数位DP
Description 找出$[L, R]$ 区间内有多少数, 各位数字和 能整除原数 Solution 枚举每个可能的数字和, 进行数位DP即可 , 水爆 Code #include<cstd ...
- [BZOJ 1799] self 同类分布
Link: BZOJ 1799 传送门 Solution: 一句话的题目,看得爽,做得烦 一般这类和数位相关的都是数位$dp$吧 不过一开始还是感觉不太可做,毕竟每个数模数不同 但要发现,模数最高也只 ...
- Bzoj 1081 [Ahoi2009] chess 中国象棋
bzoj 1081 [Ahoi2009] chess 中国象棋 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1801 状态比较难设,的确 ...
- 【BZOJ】1799: [Ahoi2009]self 同类分布
[题意]给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数.1 ≤ a ≤ b ≤ 10^18 [算法]数位DP [题解] 感觉这种方法很暴力啊. 枚举数位和1~162(不能枚举0,不然会模 ...
- BZOJ 1799 同类分布
一开始没想出来..一看题解 我艹直接枚举数位的和啊.....怪不得给50s. 还是太蠢. #include<iostream> #include<cstdio> #includ ...
- BZOJ 1799 同类分布(数位DP)
给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数.1<=a<=b<=1e18. 注意到各位数字之和最大是153.考虑枚举这个东西.那么需要统计的是[0,a-1]和[0,b ...
- BZOJ 1797: [Ahoi2009]Mincut 最小割
1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2076 Solved: 885[Submit] ...
- bzoj 1800: [Ahoi2009]fly 飞行棋 暴力
1800: [Ahoi2009]fly 飞行棋 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline ...
随机推荐
- leetcode先刷_Maximum Subarray
dp创始人级精英赛的冠军.最大的部分和. 扫从左至右,保持一个最佳值而当前部分和,在这一部分,并成为负值什么时候.再往下的积累后,也起到了负面作用,所以,放弃直销,然后部分和初始化为阅读的当前位置. ...
- 菜鸟nginx源码剖析 框架篇(一) 从main函数看nginx启动流程(转)
俗话说的好,牵牛要牵牛鼻子 驾车顶牛,处理复杂的东西,只要抓住重点,才能理清脉络,不至于深陷其中,不能自拔.对复杂的nginx而言,main函数就是“牛之鼻”,只要能理清main函数,就一定能理解其中 ...
- Arcgis for Javascript之featureLayer图和属性互操作性
说明:主要实现加载FeatureLayer并显示属性表,而要实现联动属性表与地图,首先,看看实施后的效果: 显示效果 如上图所看到的,本文章主要实现了下面几个功能:1.FeatureLayer属性表的 ...
- NSIS:使用nsWindows.nsh头文件调整窗体大小
原文 NSIS:使用nsWindows.nsh头文件调整窗体大小 此方法只能简单实现调整窗体大小,但不完美,调整后窗体上其他的控件都需要调整大小或位置,比较麻烦,轻狂不建议使用呵! ;加头文件!inc ...
- android app启动过程(转)
Native进程的运行过程 一般程序的启动步骤,可以用下图描述.程序由内核加载分析,使用linker链接需要的共享库,然后从c运行库的入口开始执行. 通常,native进程是由shell或者init启 ...
- python 架构简介(转)
前言: 开发语言python 越来越火 ,作为开发比较火的语言,python 对网页等的支持也很好,当你想用python来写网页的时候你就要选择框架了.到底要选择呢什么样子的框架,最适合你的项目 ...
- 什么是WEBserver? 经常使用的WEBserver有哪些?
什么是WEBserver? 经常使用的WEBserver有哪些? 一.什么是WEBserver Webserver能够解析HTTP协议.当Webserver接收到一个HTTP请求,会返回一个HTTP响 ...
- 【UVA】11137-Ingenuous Cubrency
DP问题,须要打表. dp[i][j]代表利用大小不超过i的数字组成j的方法. 状态方程是 dp[i][j] = d[i - 1][j] + sum{dp[i - 1][j - k * i * i * ...
- 面向对象三大特征之继承(extends)——Java笔记(六)
继承: 从一般到特殊的关系,是一种拓展关系,子类对象是父类的一种,也可称为”is a“的关系 泛化: 把子类里的共性抽取到父类里的来的过程 特化: ...
- I2C驱动程序框架probe道路
基于Linux的I2C驱动器.采纳probe道路.根据这个框架,如下面就可以写任何支持I2C总线设备Linux驱动器. I2C设备连接到cpu具体i2c接口.被安装在cpu的i2c适配器.i2c设备和 ...