ABC448E Simple Division 题解
ABC488E Simple Division
给定一个大数 \(N\) 和 \(m\),询问 \(\lfloor N/m\rfloor\) 对 \(10007\) 取模的值。
这里大数 \(N\) 这样给出,给出 \(K\) 个形如 \(c_i,l_i\) 的数对,并一开始有个空串 \(S\)。
第 \(i\) 次将字符 \(c_i\in\{0,1,2,3,4,5,6,7,8,9\}\) 复制 \(l_i\) 份加入到 \(S\) 的末尾,最后将 \(S\) 转化为大数 \(N\)。
\(m\leq10^4,K\leq 10^5,l_i\leq 10^9\)
赛时没想出来怎么做,学到了新 trick:
将原查询转化为 \(\lfloor(N\bmod 10007m)/m\rfloor\bmod 10007\)。
这样只需要在运算过程中对 \(P=10007m\) 取模就行。
然后我们要计算的是这样一个式子
\[N=\sum_{i=1}^{K} c_i\times \frac{10^{l_i}-1}{9}\times10^{\sum_{j=i+1}^K l_j}
\]
由于在新模数下 \(9\) 的逆元可能不存在,有以下两种方法(均来自官方题解):
- 定义 \(R(l)\) 表示一段长为 \(l\) 的 \(1\) 的值,我们要求出 \(l=2^k\) 即 \(2\) 的整数次幂时的 \(R\) 值。又 \(R(x+y)=R(x)\times 10^y+R(y)\),求出 \(R(2^k)\) 的值后可以组合求出任意的 \(R\) 值(类似快速幂)。
- 考虑求 \(9N\) 的值,记为 \(N'\),那么即求 \(\lfloor N'/9\rfloor\) 对 \(10007m\) 取模。类比一开始的方法,我们再变成对 \(9\times 10007m\) 取模即可。
方法2:
ll p=10007;
inline ll fpr(ll b,ll t=p-2,ll x=1ll){
for(;t;t>>=1,b=b*b%p)
if(t&1)x=x*b%p;
return x;
}
ll m,k,l[N],c[N],s[N];
int main(){
cin>>k>>m;p*=9,p*=m;
for(int i=1;i<=k;++i){
cin>>c[i]>>l[i];
s[i]=s[i-1]+l[i];
}
ll N=0;
for(int i=1;i<=k;++i){
N=(N+c[i]*fpr(10ll,s[k]-s[i])%p*(fpr(10ll,l[i])-1+p)%p)%p;
}
N/=9ll,N/=m;
cout<<N%10007<<'\n';
return 0;
}

浙公网安备 33010602011771号