题解:P9006 [入门赛 #9] 神树大人挥动魔杖 (Hard Version)
_MiyazonoKaori_ · · 题解
upd 2025.2.22:修改了格式
1. 纯暴力(只过样例,0pts):
#include<bits/stdc++.h>
#define fast_gets ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int ans[1005];
int main(){
fast_gets
int n,k;
cin>>n>>k;
for(int i=1;i<=9*pow(10,n-1);i++){
for(int j=0;j<k;j++){
if(i%k==j) ans[j]++;
}
}
for(int i=0;i<k;i++) cout<<ans[i]<<' ';
return 0;
}
代码就不解释了。
2. 差分(100pts):
思路:
精灵的个数为
同理可设有一个函数
其中:
这个表达式表示的是在从
每一组精灵至少有
AC 代码(纯净版):
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define fast_gets ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int N=1e6+5,MOD=1e8+7;
int cnt[N];
ll f(ll a,ll b,ll c){
ll ans=1;
while(b){
if(b&1) ans=ans*a%c;
a=a*a%c;
b>>=1;
}
return ans;
}
int main(){
fast_gets
int n,k;
cin>>n>>k;
ll maxn=(f(10,n-1,k)-1+k)%k;
ll p=(f(10,n-1,MOD)-1-maxn+MOD)*f(k,MOD-2,MOD)%MOD;
for(int i=0;i<k;i++){
cnt[i]=-p;
if(i>0&&i<=maxn) cnt[i]--;
}
maxn=(f(10,n,k)-1+k)%k;
p=(f(10,n,MOD)-1-maxn+MOD)*f(k,MOD-2,MOD)%MOD;
for(int i=0;i<k;i++){
cnt[i]+=p;
if(i>0&&i<=maxn) cnt[i]++;
cnt[i]=(cnt[i]+MOD)%MOD;
cout<<cnt[i]<<' ';
}
return 0;
}