QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#555829#4169. 代码拍卖会David_Mercury10 97ms23552kbC++143.7kb2024-09-10 10:38:012024-09-10 10:38:02

Judging History

你现在查看的是最新测评结果

  • [2024-09-10 10:38:02]
  • 评测
  • 测评结果:10
  • 用时:97ms
  • 内存:23552kb
  • [2024-09-10 10:38:01]
  • 提交

answer

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int MAXN = 505, MAXLOG = 25;
const ll Mod = 999911659;
ll n, p, w = 20, f[MAXLOG][MAXN][2], g[MAXN], inv[MAXN], h[MAXN][MAXLOG][MAXN], Bit[MAXN];

inline ll Quick_Power(ll x, ll p, ll Mod){
	if(!p)	return 1;
	ll tmp = Quick_Power(x, p>>1, Mod);
	if(p&1)	return tmp*tmp%Mod*x%Mod;
	else	return tmp*tmp%Mod;
}

int main(){
	cin>>n>>p;
	ll x = n;
	for(int i = 1; i <= w; i++, x /= 10)	Bit[i] = x%10;
	g[0] = 1;
	for(int i = 1; i <= p; i++)	g[i] = g[i-1]*10%p;
	f[0][1][1] = f[0][1][0] = 1;
	for(int i = 1; i <= w; i++)
		for(int j = 0; j < p; j++){
			int x = 1;
			for(int k = 1; k <= 10; k++)	x = x*j%p;
			for(int k = 0; k < 10; k++){
				if(k < Bit[i])	(f[i][x*g[k]%p][1] += f[i-1][j][0]) %= Mod;
				if(k == Bit[i])	(f[i][x*g[k]%p][1] += f[i-1][j][1]) %= Mod;
				(f[i][x*g[k]%p][0] += f[i-1][j][0]) %= Mod;
			}
		}
//	for(int i = 0; i < p; i++)	cout<<f[w][i][1]<<" "; puts("");
	inv[0] = 1;
	for(int i = 1; i <= 8; i++)	inv[i] = Quick_Power(i, Mod-2, Mod)%Mod;
	h[0][0][0] = 1;
	for(int i = 0; i < p; i++)
		for(int j = 0; j <= 8; j++)
			for(int k = 0; k < p; k++){
				ll ans = 1;
				for(int t = 0; t <= j; t++){
					(h[i+1][j][k] += h[i][j-t][(k-i*t%p+p)%p]*ans) %= Mod;
					ans = ans*(f[w][i][1]+t)%Mod*inv[t+1]%Mod;
				}
			}
//	for(int i = 0; i < p; i++)
//		for(int j = 0; j <= 8; j++)
//			for(int k = 0; k < p; k++)	cout<<i<<" "<<j<<" "<<k<<"  "<<h[i][j][k]<<endl;
	int tmp = (p-Quick_Power(10, n, p)+9)%p;
//	cout<<tmp<<endl;
	cout<<h[p-1][8][tmp];
	
	return 0;
}
/*
我猜还是矩阵乘法(不对,n^3 就已经爆 1e8 了)
f[j][i][k]:数码为 i,第 j 位,模 p 余 k
f[j+1][t][(k+t)%p] += f[j][i][k], t >= i
如果 p <= 10 的话这倒是可以矩阵乘法计算(为了避免爆栈,不要写递归ksm)
而当 p > 10 的话这实际可以线性递推出来,因为每个状态唯一对应一个前驱……
并不正确。因为 k 虽然一样,可能存在多个 i

或许注意力偏了,这本质是一道数论题
111...11 = (10^len-1)/9
经过推导,有:9*10^n - 1 = \sum_{i=1}^8 10^{x_i}, 0 <= x_i <= n 且 x_i 单调递增 
然后可以设法算出 f[x] 表示 10^y mod p = x 的个数
怎么算?其实可以数位 DP
那么如何求出最终的 x_i 可重集?
如果没有 x_i 是集合的限制,其实很简单。 
钦定一个数 v_i 为最小值,然后将它提出来,继续处理剩下的数——但这么做,上界无法保证。
或许可以尝试容斥?不可以。

式子推错了(
\sum_{i=1}^8 10^{x_i} = -10^n+9,0 <= x_i <= n 且 x_i 单调递增

如果没有 x_i 是多重集的限制,其实有一个简单 DP:
h[i][j] 表示前 i 个数码,余数为 j,然后通过枚举这一位填的余数 k 转移
这里有一个奇妙 Trick:如果我们最开始就枚举转移 k,就可以等同于枚举集合(类似多重背包)
但同一 k 的方案之间仍可能存在重复,需要处理如下问题:
现有 a 种物品,你要从中选出 b 个,每种物品数量不限,求方案数
多重集的组合数(无限)
可以等价为 (1+x+x^2+...+x^b)^a[x^b]
其实已经可以用生成函数了,但能不能再简单一点?
 = (1-x)^(-a)[x^b]
再用二项式定理展开:
\sum_{i=0}^inf (-1)^i a^{i上升幂}/i! (-x)^i = \sum_{i=0}^inf a^{i上升幂}/i! x^i
那么答案就是 a^{b 次上升幂}/b!

怎么过不了样例???
哦!
如果 9 在模 p 意义下为 0 最开始的结论就不成立
但显然这仅当 p=1/3/9 时有可能
而能被 1/3/9 整除的数有数字和也能被二者整除的特性
有个简单的矩阵快速幂做法:f[i][j][k]:前 j 个数码,数码和模 p 

82749201374821543 5
*/

Details

Tip: Click on the bar to expand more detailed information

Pretests


Final Tests

Test #1:

score: 0
Wrong Answer
time: 63ms
memory: 22244kb

input:

982 473

output:

224546702

result:

wrong answer 1st lines differ - expected: '885655151', found: '224546702'

Test #2:

score: 10
Accepted
time: 1ms
memory: 3816kb

input:

82749201374821543 5

output:

209850746

result:

ok single line: '209850746'

Test #3:

score: 0
Wrong Answer
time: 1ms
memory: 3976kb

input:

17327482917364121 7

output:

348009270

result:

wrong answer 1st lines differ - expected: '556848847', found: '348009270'

Test #4:

score: 0
Wrong Answer
time: 0ms
memory: 5844kb

input:

28489124728192763 1

output:

0

result:

wrong answer 1st lines differ - expected: '720894199', found: '0'

Test #5:

score: 0
Wrong Answer
time: 1ms
memory: 4588kb

input:

40285729174762941 25

output:

0

result:

wrong answer 1st lines differ - expected: '370754148', found: '0'

Test #6:

score: 0
Wrong Answer
time: 97ms
memory: 23552kb

input:

999999 499

output:

945835207

result:

wrong answer 1st lines differ - expected: '974444728', found: '945835207'

Test #7:

score: 0
Wrong Answer
time: 3ms
memory: 7852kb

input:

58390378572931426 113

output:

382292627

result:

wrong answer 1st lines differ - expected: '633268808', found: '382292627'

Test #8:

score: 0
Wrong Answer
time: 93ms
memory: 23004kb

input:

38475729495732951 491

output:

483591057

result:

wrong answer 1st lines differ - expected: '750948889', found: '483591057'

Test #9:

score: 0
Wrong Answer
time: 92ms
memory: 23020kb

input:

71937591037847128 487

output:

431986017

result:

wrong answer 1st lines differ - expected: '621801725', found: '431986017'

Test #10:

score: 0
Wrong Answer
time: 82ms
memory: 23116kb

input:

100000000000000000 491

output:

741182107

result:

wrong answer 1st lines differ - expected: '725090268', found: '741182107'