數數 (數學)(快速冪+同餘定理)
阿新 • • 發佈:2019-02-03
- 數數
【問題描述】
小 Star 還不會數數。有一天他看到了一張奇怪的數表,上面的每一個數各自都由相同數字構成,比如“11111111”“66666” 。於是他想自己從 1 慢慢數到這個數字。多少 Star 有個很不好的習慣,每數到一定個數就會從頭開始數起。
現在請你幫忙求出,他最後數出來的數是多少。
【輸入】
第一行一個整數 Q,表示數表上總共有多少個數;
以下 Q 行每行三個整數 x、n、p,表示這一次 Star 要數 n 個連續的 x,並且每數到 p 就歸零。
【輸出】
輸出 Q 行,按順序表示 Star 這一次數出來的數字是多少。
【輸入輸出樣例】
count.in
3
8 5 3
3 3 1
5 3 4
count.out
1
0
3
N 個 X 連在一起,這個數能不能直接表示出來?答案是肯定的,它等於(10^n- 1) / 9 * X。當 P 為質數時,顯然 9 對模 P 有逆元,直接計算即可;若 P 不為質數,我們也只需要根據下式做一個小小的轉化:
T / K % P = T % KP / K.
(證:T / K = sP + r,0 ≤ r < P,則 T = sPK + rK,0 ≤ rK < PK。 )
換言之,我們只要事先將 P 乘上 9,最終再把答案除以 9 就可以
解決不互質的情況了。
單組時間複雜度:O(logN)。
program mys;
var ii,i,j,k,m,q:longint;
ans,x,n,p,qq:int64;
function fa(x,n:int64):int64;
var t,y:int64;
begin
t:=x; y:=1;
while n>0 do
begin
if n and 1=1 then
y:=((y mod p)*(t mod p))mod p;
t:=((t mod p)*(t mod p)) mod p;
n:=n div 2;
end;
exit(y mod p);
end;
begin
assign(input,'count.in'); reset(input);
assign(output,'count.out'); rewrite(output);
readln(q);
for ii:=1 to q do
begin
readln(x,n,p);
qq:=p;
p:=p*9;
ans:=fa(10,n)mod p;
ans:=x*(ans-1 mod p+p) mod p;
ans:=(ans div 9)mod qq;
writeln(ans mod qq);
end;
close(input); close(output);
end.