被虐的体无完肤,
直接给题解地址吧:http://vfleaking.blog.163.com/blog/static/174807634201341721051604/
1 const maxk=1000010; 2 type matrix=array[1..3,1..3] of int64; 3 var a:array[0..maxk*6] of longint; 4 first,last,b,len:array[0..maxk] of longint; 5 pre:array[0..maxk] of longint; 6 n,k,p,x,y,sum:int64; 7 i,j:longint; 8 ans,aa,bb,s:matrix; 9 10 function ni(x:int64; y:longint):int64; 11 begin 12 ni:=1; 13 while y>0 do 14 begin 15 if y mod 2=1 then ni:=ni*x mod k; 16 y:=y div 2; 17 x:=x*x mod k; 18 end; 19 end; 20 21 procedure work; 22 var i,d,ph:longint; 23 begin 24 a[1]:=1;a[2]:=1;i:=2; 25 while true do 26 begin 27 inc(i); 28 a[i]:=(a[i-1]+a[i-2]) mod k; 29 if first[a[i]]=0 then first[a[i]]:=i; 30 if (a[i]=1) and (a[i-1]=1) then break; 31 end; 32 d:=k; 33 ph:=k; 34 for i:=2 to trunc(sqrt(k)) do 35 if d mod i=0 then 36 begin 37 ph:=ph div i*(i-1); 38 while d mod i=0 do d:=d div i; 39 end; 40 if d>1 then ph:=ph div d*(d-1); 41 42 for i:=1 to k-1 do 43 begin 44 pre[i]:=ni(i,ph-1); 45 if int64(pre[i])*int64(i) mod k<>1 then pre[i]:=0; 46 // writeln(pre[i]); 47 end; 48 b[1]:=1;last[1]:=1;i:=1; 49 while true do 50 begin 51 len[i]:=first[pre[b[i]]]-1; 52 if len[i]<0 then break; 53 inc(i); 54 b[i]:=int64(a[len[i-1]])*b[i-1] mod k; 55 if last[b[i]]>0 then break; 56 last[b[i]]:=i; 57 end; 58 aa[1,2]:=1; aa[2,1]:=1; aa[2,2]:=1; aa[3,3]:=1; 59 bb:=aa; bb[3,2]:=p-1; 60 end; 61 62 operator *(a,b:matrix)c:matrix; 63 var i,j,k:longint; 64 begin 65 for i:=1 to 3 do 66 for j:=1 to 3 do 67 begin 68 c[i,j]:=0; 69 for k:=1 to 3 do 70 c[i,j]:=(c[i,j]+a[i,k]*b[k,j]) mod p; 71 end; 72 end; 73 74 function f(a:matrix;n:int64):matrix; 75 begin 76 fillchar(f,sizeof(f),0); 77 f[1,1]:=1;f[2,2]:=1;f[3,3]:=1; 78 while n>0 do 79 begin 80 if n and 1=1 then f:=f*a; 81 a:=a*a; 82 n:=n div 2; 83 end; 84 end; 85 86 begin 87 readln(n,k,p); 88 if n<3 then 89 begin 90 writeln(1); 91 exit; 92 end; 93 work; 94 ans[1,1]:=1; ans[2,2]:=1; ans[3,3]:=1; 95 if n>len[1] then 96 begin 97 dec(n,len[1]+1); 98 ans:=ans*f(aa,len[1]-2)*bb; 99 end 100 else begin 101 ans:=ans*f(aa,n-2); 102 n:=0; 103 end; 104 i:=2; 105 while n>0 do 106 begin 107 if (pre[b[i]]=0) or (len[i]<0) then 108 begin 109 ans:=ans*f(aa,n); 110 n:=0; 111 break; 112 end; 113 if last[b[i]]<i then break; 114 if n>len[i] then 115 begin 116 dec(n,len[i]+1); 117 ans:=ans*f(aa,len[i])*bb; 118 end 119 else begin 120 ans:=ans*f(aa,n); 121 n:=0; 122 end; 123 inc(i); 124 end; 125 if n<>0 then 126 begin 127 j:=i; 128 sum:=0; 129 fillchar(s,sizeof(s),0); 130 s[1,1]:=1; s[2,2]:=1; s[3,3]:=1; 131 for i:=last[b[j]] to j-1 do 132 begin 133 inc(sum,len[i]+1); 134 s:=s*f(aa,len[i])*bb; 135 end; 136 ans:=ans*f(s,n div sum); 137 n:=n mod sum; 138 i:=last[b[j]]; 139 while n>0 do 140 begin 141 if n>len[i] then 142 begin 143 ans:=ans*f(aa,len[i])*bb; 144 dec(n,len[i]+1); 145 end 146 else begin 147 ans:=ans*f(aa,n); 148 n:=0; 149 end; 150 inc(i); 151 end; 152 end; 153 writeln((ans[1,2]+ans[2,2]+ans[3,2]) mod p); 154 end.
时间: 2024-11-26 07:22:05