在1, 11, 111……中选<=8个, + 11..(n个1)拼出所有可能...这些数mod p至多有p中可能, 找出循环的处理一下. 那么dp就很显然了...dp(i, j, k)表示前i种选出了j个, 组合出的数mod p = k, 然后递推一下就好了.

-----------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
typedef long long ll;
 
const int maxn = 509;
const int maxm = 1000;
const int MOD = 999911659;
const int n = 9;
 
int dp[2][maxm][maxn], Inv[maxm], C[maxn][maxm], cir[maxn];
int P, R;
ll N, cnt[maxn];
 
void Gcd(int a, int b, int &d, ll &x, ll &y) {
if(!b) {
d = a;
x = 1;
y = 1;
} else {
Gcd(b, a % b, d, y, x);
y -= x * (a / b);
}
}
 
int _C(ll n, int m) {
if(m > n)
return 0;
int ret = 1;
for(ll x = n - m + 1; x <= n; x++)
ret = ll(ret) * (x % MOD) % MOD;
return ll(ret) * Inv[m] % MOD;
}
 
void Init() {
memset(cnt, 0, sizeof cnt);
scanf("%lld%d", &N, &P);
int x = 1 % P, sz = 0;
while(!cnt[x]) {
cir[cnt[x] = ++sz] = x;
if(sz >= N)
break;
x = (x * 10 + 1) % P;
}
if(sz != N) {
ll _N = N - cnt[x] + 1;
int  _sz = sz - cnt[x] + 1;
if(_sz > 1)
R = P - cir[cnt[x] + (_N % _sz ? _N % _sz : _sz) - 1];
else
R = P - cir[cnt[x]];
for(int i = 0, t = cnt[x]; i < P; i++) if(cnt[i]) {
if(cnt[i] < t)
cnt[i] = 1;
else
cnt[i] = _N / _sz + (_sz > 1 && (_N % _sz) > cnt[i] - t);
}
} else {
R = P - x;
for(int i = 0; i < P; i++)
if(cnt[i]) cnt[i] = 1;
}
if(R >= P)
R -= P;
for(int i = 0, fac = 1; i < n; i++, fac = i * fac % MOD) {
int d;
ll x, y;
Gcd(fac, MOD, d, x, y);
Inv[i] = (x + MOD) % MOD;
}
for(int i = 0; i < P; i++)
for(int j = 0; j < n; j++)
if(cnt[i]) C[i][j] = _C(cnt[i] + j - 1, j);
}
 
inline void upd(int &x, int t) {
if((x += t) >= MOD)
x -= MOD;
}
 
int main() {
Init();
int c = 0, p = 1;
dp[c][0][0] = 1;
for(int i = 0; i < P; i++) if(cnt[i]) {
swap(c, p);
for(int j = 0; j < n; j++)
for(int k = 0; k < P; k++)
dp[c][j][k] = dp[p][j][k];
for(int j = 0; j < n; j++)
for(int k = 0; k < P; k++) if(dp[p][j][k])
for(int t = 1; t + j < n; t++)
upd(dp[c][j + t][(k + t * i) % P], ll(dp[p][j][k]) * C[i][t] % MOD);
}
int ans = 0;
for(int i = 0; i < n; i++)
upd(ans, dp[c][i][R]);
printf("%d\n", ans);
return 0;
}

-----------------------------------------------------------------------

1974: [Sdoi2010]auction 代码拍卖会

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 263  Solved: 97
[Submit][Status][Discuss]

Description

随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代码库。猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库。iPig不想把代码库给所有想要的小猪,只想给其中的一部分既关系好又肯出钱的小猪,于是他决定举行了一个超大型拍卖会。 在拍卖会上,所有的N头小猪将会按照和iPig的好感度从低到高,从左到右地在iPig面前站成一排。每个小猪身上都有9猪币(与人民币汇率不明),从最左边开始,每个小猪依次举起一块牌子,上面写上想付出的买代码库的猪币数量(1到9之间的一个整数)。大家都知道,如果自己付的钱比左边的猪少,肯定得不到梦寐以求的代码库,因此从第二只起,每只猪出的钱都大于等于左边猪出的价钱。最终出的钱最多的小猪(们)会得到iPig的代码库真传,向着保送PKU(Pig Kingdom University)的梦想前进。 iPig对自己想到的这个点子感到十分满意,在去现场的路上,iPig就在想象拍卖会上会出现的场景,例如一共会出现多少种出价情况之类的问题,但这些问题都太简单了,iPig早已不敢兴趣了,他想要去研究更加困难的问题。iPig发现如果他从台上往下看,所有小猪举的牌子从左到右将会正好构成一个N位的整数,他现在想要挑战的问题是所有可能构成的整数中能正好被P整除的有多少个。由于答案过大,他只想要知道答案mod 999911659就行了。

Input

有且仅有一行:两个数N(1≤N≤10^18)、P(1≤P≤500),用一个空格分开。

Output

有且仅有一行:一个数,表示答案除以999911659的余数。

Sample Input

2 3

Sample Output

15
样例解释
方案可以是:12 15 18 24 27 33 36 39 45 48 57 66 69 78 99,共15种。
数据规模
测试点 N P 测试点 N P
1 ≤1000 ≤500 6 ≤10^6 ≤500
2 ≤10^18 5 7 ≤10^18 ≤120
3 ≤10^18 ≤10 8 ≤10^18 ≤500
4 ≤10^18 ≤10 9 ≤10^18 ≤500
5 ≤10^18 25 10 ≤10^18 ≤500

HINT

Source

BZOJ 1974: [Sdoi2010]auction 代码拍卖会( dp )的更多相关文章

  1. BZOJ 1974 [Sdoi2010] auction 代码拍卖会(数位dp)

    题目描述 随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代码库.猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库.iPig不想把代码库给所有想要的小猪,只想给其中的一部分既关 ...

  2. BZOJ 1974 [Sdoi2010]auction 代码拍卖会 ——动态规划

    把每一位上不递减的数拆成1+11+11111+11111+..... 然后就可以把巨大的N从复杂度中消掉,因为随着长度的增加1...111%p出现了循环节. 然后就是从n个数中选出几个使他们结果为0( ...

  3. 【BZOJ-1974】auction代码拍卖会 DP + 排列组合

    1974: [Sdoi2010]auction 代码拍卖会 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 305  Solved: 122[Submit ...

  4. Bzoj1974 [Sdoi2010]auction 代码拍卖会

    Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 375  Solved: 151 Description 随着iPig在P++语言上的造诣日益提升,他形成 ...

  5. bzoj 1974: [Sdoi2010]代码拍卖会

    Description 随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代 码库.猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库.iPi g不想把代码库给所有想要的小猪,只想 ...

  6. [SDOI2010]代码拍卖会——DP

    原题戳这里 绝对是一道好题 需要注意到两个东西 1.符合条件的数可以拆成一堆\(11...11\)相加的形式,比如\(1145=1111+11+11+11+1\) 2.\(1,11,111,1111, ...

  7. Luogu2481 SDOI2010 代码拍卖会 DP、组合

    传送门 神仙DP 注意到\(N \leq 10^{18}\),不能够直接数位DP,于是考虑形成的\(N\)位数的性质. 因为低位一定不会比高位小,所以所有满足条件的\(N\)位数一定是不超过\(9\) ...

  8. bzoj 1925 [Sdoi2010]地精部落(DP)

    Description 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi, ...

  9. bzoj 1925: [Sdoi2010]地精部落【dp】

    设[f[i][j]为1到i,开头数字是j并且是山峰的方案数 注意到当数字j和j-1不相邻时,交换它们会得到一个新的符合要求的序列,所以f[i][j]+=f[i][j-1]; 如果相邻,那么j是山峰,j ...

随机推荐

  1. Web API核查表:设计、测试、发布API时需思考的43件事[转]

    Web API核查表:设计.测试.发布API时需思考的43件事   当设计.测试或发布一个新的Web API时,你是在一个原有的复杂系统上构建新的系统.那么至少,你也要建立在HTTP上,而HTTP则是 ...

  2. session相关----高手请跳过!

    session["username"]=null;//Session.Remove("username");的结果是session["username ...

  3. IsNullOrEmpty和s == null || s.Length == 0哪个快

    在写扩展方法时,看到有人用==null这个方法,说快,上网找了些资料,最后在csdn的博客上看到了一篇文章,说实测是后两者快,于是我也试着做了一个程序运行了一下,却发现这样的结果: 我测试了一个,发现 ...

  4. bootstrap注意事项(三)

    1.<code> 标签用于表示计算机源代码或者其他机器可以阅读的文本内容.软件代码的编写者已经习惯了编写源代码时文本表示的特殊样式.<code> 标签就是为他们设计的.包含在该 ...

  5. Ubuntu Code::Blocks IDE 13.12 汉化

    Ubuntu Code::Blocks IDE 13.12 汉化: 安装很简单,不再赘述. 单说汉化: .下载中文简体汉化包(百度网盘):链接: http://pan.baidu.com/s/1kU3 ...

  6. SqlServer mssql 按月统计所有部门

    以订单统计为例,前端展示柱状图(Jquery统计): 表及主要字段描述如下:表名:Orders1.日期CreateTime2.金额Amount3.用户UserID 情况一:根据部门统计某一年每月销量( ...

  7. 在MyEclipse环境下写Struts,删除项目不干净的问题的解决

    这个头疼的问题弄了好几个小时,终于弄好了.方法如下:1.建立一个新的项目,确认自己已经部署好Struts2的环境(网上有好多教程).运行Tomcat还是会有之前的项目的错误,接下来进行第二步2.将To ...

  8. xsqlbuilder使用说明

    动态构造sql的利器:rapid-xsqlbuider详细说明 特性列表: 动态构造sql条件语句,提供sql拼接与使用占位符两种方式 数据类型的修饰 对SQL注入攻击的防范 问题: 手工构造SQL语 ...

  9. Socket 服务器和客户端通信

    //服务器端package com.svse.service; import java.io.BufferedReader; import java.io.IOException; import ja ...

  10. jQuery 源码分析和使用心得 - 文档遍历 ( traversing.js )

    jQuery之所以这么好用, 首先一点就是$()方法和它强大的选择器. 其中选择器使用的是sizzle引擎, sizzle是jQuery的子项目, 提供高效的选择器查询. 有个好消息告诉大家, 就是s ...