2019 Nanchang ICPC network game H The Nth Item

The Nth Iteam

The meaning of problems: F (0) = 1, F (1) = 1, F (n) = 3 * F (n-1) + 2 * F (n> = 2) (n-2), F (n) MOD . 9 . 9 . 8 2 . 4 . 4 . 3 . 5 . 3. With given Q N . 1 , N I = N I. 1- ^ (F. (N I-. 1 ) * F. (N I-. 1 )), find F. (N . 1 ) ^ F. (N 2 ) ^ ... ^ F. (N Q )

H E data with this game are very water, but the problem is good.

When the game is seeking a cycle festival, we were descending the matrix, and then ran out of the local + test data sets 1e7 within the time limit, dare post, but did not expect so water data matrix fast power + map memory of what can be had.

 1 #include<cstdio>
 2 #include<tr1/unordered_map>
 3 using namespace std;
 4 typedef long long ll;
 5 const int N=1e7+11,md=998244353;
 6 tr1::unordered_map<ll,int> mmp;
 7 ll aa[N],f[N];
 8 struct Matrix{
 9     int r,c;
10     ll a[5][5];
11     Matrix(){}
12     Matrix(int r,int c):r(r),c(c){
13         for(int i=0;i<r;i++)
14             for(int j=0;j<c;j++) a[i][j]=0;
15     }
16 };
17 Matrix mmul(Matrix m1,Matrix m2,ll z){
18     Matrix ans(m1.r,m2.c);
19     for(int i=0;i<m1.r;i++)
20         for(int j=0;j<m2.c;j++)
21             for(int k=0;k<m1.c;k++){
22                 ans.a[i][j]+=m1.a[i][k]*m2.a[k][j]%z;
23                 if(ans.a[i][j]>=z) ans.a[i][j]-=z;
24             }
25     return ans;
26 }
27 Matrix mpow(Matrix m1,ll y,ll z){
28     Matrix ans(m1.r,m1.c);
29     for(int i=0;i<ans.r;i++) ans.a[i][i]=1;
30     while(y){
31         if(y&1) ans=mmul(ans,m1,z);
32         m1=mmul(m1,m1,z);
33         y>>=1;
34     }
35     return ans;
36 }
37 
38 int main(){
39     f[0]=0;f[1]=1;
40     for(int i=2;i<N;i++) f[i]=(f[i-1]*3ll%md+f[i-2]*2ll%md)%md;
41     int q,pos1,pos2,len,num,yu;
42     ll n,m,ans;
43     while(~scanf("%d%lld",&q,&n)){
44         ans=aa[0]=0;
45         mmp.clear();
46         pos1=pos2=-1;
47         for(int i=1;i<=q;i++){
48             if(n<N) aa[i]=f[n];
49             else{
50                 m=n-1;
51                 if(m>=md-1) m%=md-1; 
52                 Matrix A(2,1),T(2,2);
53                    A.a[0][0]=1;
54                    T.a[0][0]=3;T.a[0][1]=2;T.a[1][0]=1;
55                 T=mpow(T,m,md);
56                 A=mmul(T,A,md);
57                 aa[i]=A.a[0][0];
58             }
59             if(n==0) break;
60             if(mmp[n]){
61                 pos1=mmp[n];
62                 pos2=i;
63                 break;
64             }
65             else mmp[n]=i;
66             ans^=aa[i];
67             n=n^(aa[i]*aa[i]);
68             aa[i]^=aa[i-1];
69         }
70         if(pos1!=-1){
71             len=pos2-pos1;
72             num = (q-pos2 + 1 ) / len;
73              yu = (q-pos2 + 1 )% len;
74              if (num + 1 ) ans = ^ aa [pos2- 1 ] ^ aa [pos1- 1 ];
75              if (yu) ans = ^ aa [yu- pos1 + 1 ] ^ aa [pos1- 1 ];
76          }
 77          printf ( " % lld \ n " , ans);
78      }
 79      return  0 ;    
80 }
We should not be too

But in fact they want to look, Q equals 1e7, the middle and then set log, then there are some constants of fast power matrix calculation, it is clear that T will fall, apart from the water in the past, or to learn some of the O (1) approach.

First, this series is obviously a linear recurrence Sequence, then we can order it in a general term formula, the specific method for finding 360 words there are several, I direct studied first method: using the characteristic equation (linear algebra solution) the solution .

Overview of the characteristic equation

A number of columns: X (n + 2) = C1X (n + 1) + C2Xn

Provided r, s that the X (n + 2) -rX (n + 1) = s [X (n + 1) -rXn]

Therefore, X (n + 2) = (s + r) X (n + 1) -srXn

C1=s+r

C2=-sr

Wherein deriving the equation to eliminate s r * r-C1 * r-C2 = 0

We C1 = 3, C2 = 2, there can be lifted substituting r = (3 + √17) / 2, s = (3-√17) / 2

Then F. (N-) = X . 1 * R & lt n- + X 2 * S n- , we have F (0) = 0, F (1) = 1, substituting can solve for X . 1 =. 1 / √17, X 2 = -1 / √17

Then the term formula appeal is the number of columns F. (N-) =. 1 / √17 * (((√17. 3 +) / 2) n- - ((. 3-√17) / 2) n- )

The solution contains a lot of knowledge of linear algebra, do not understand can go to learn about the undetermined coefficient method for finding geometric series, or look at the Fibonacci Sequence by formula is deduced how? , Which has a matrix derivation process.

Back to this question, we have a formula of general term, √17, then, in front of the blog have talked about quadratic residue, then by x 2 ≡17 (MOD 9 9 8 2 4 4 3 5 3 can be obtained x) Instead of √17, then we can divide the inside of the inverse yuan, which can be obtained the first.

Related code is as follows:

 1 #include<cstdio>
 2 #include<ctime>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 using namespace std;
 6 const int md=998244353;
 7 typedef long long ll;
 8 struct Fp2{
 9     ll x,y;
10 };
11 ll w;
12 Fp2 fmul(const Fp2 &f1,const Fp2 &f2){
13     Fp2 ans;
14     ans.x=(f1.x*f2.x%md+f1.y*f2.y%md*w%md)%md;
15     ans.y=(f1.x*f2.y%md+f1.y*f2.x%md)%md;
16     return ans;
17 }
18 Fp2 fpow(Fp2 x,ll y){
19     Fp2 ans;
20     ans.x=1;ans.y=0;
21     while(y){
22         if(y&1) ans=fmul(ans,x);
23         x=fmul(x,x);
24         y>>=1;
25     }
26     return ans;
27 }
28 ll poww(ll x,ll y){
29     ll ans=1;
30     while(y){
31         if(y&1){
32             ans*=x;
33             if(ans>=md) ans%=md;
34         }
35         x*=x;
36         if(x>=md) x%=md;
37         y>>=1;
38     }
39     return ans;
40 }
41 ll cipolla(ll x){
42     if(x==0) return 0;
43     if(x==1) return 1;
44     if(poww(x,(md-1)>>1)+1==md) return -1;
45     ll a;
46     while(true){
47         a=rand()%md;
48         w=((a*a%md-x)%md+md)%md;
49         if(poww(w,(md-1)>>1)+1==md) break;
50     }
51     Fp2 ans;
52     A = ans.x; ans.y = . 1 ;
 53 is      ANS = fpow (ANS, (MD + . 1 ) >> . 1 );
 54 is      return ans.x;
 55  }
 56 is  int main () {
 57 is      srand (Time (NULL)) ;
 58      LL = PY17 Cipolla ( 17 ), NV2 = poww ( 2 , the MD- 2 );
 59      the printf ( " root of the quadratic residue 17: LLD% \ n- " , PY17);
 60      the printf ( " inverse element 2 : LLD% \ n- " , NV2);
 61 is      the printf ( " root of the quadratic residue inverse element 17: LLD% \ n- ", poww (PY17, the MD- 2 ));
 62 is      the printf ( " 3+ root 7 except 2: LLD% \ n- " , (( . 3 + PY17) NV2% *% MD MD)% MD);
 63 is      the printf ( " 3- root 7 except 2: LLD% \ n- " , ((( . 3 -py17)% MD + MD)%% MD MD * NV2)% MD); 
 64      return  0 ;
 65 }
Duck hit the table

Wherein a set of results:

 

 So this time, we have set up aa = 736044383, bb = 262199973, we quickly determined power can log F (n)

But this is not enough, what we need is O (1), so we can first block pretreatment.

How to do it, then of aa, bb in 9 MOD 9 8 2 4 4 3 5 the sense 3, is already an integer, so the demand AA n or bb n when n is large, you can be in front of us cycle index Euler section in the descending, i.e. n-% = n-. 9 . 9 . 8 2 . 4 . 4 . 3 52 is +. 9 . 9 . 8 2 . 4 . 4 . 3 52 is (. 9 . 9 . 8 2 . 4 . 4 . 3 . 5 2 9 . 9 . 8 2 . 4 . 4 . 3 . 5 3 is the Euler function )

N is the maximum time 1996488703, √1996488703 = 44682.084810357719028060186400879, then we can 5E4 (not less than 44683) is a component block, and we first pretreated with a power bb aa 0, the power 1 to power 5E4 then pretreated 0 * 5e4 power, 1 * 5e4 5e4 * 5e4 power to power

So when we ask aa or bb n power when the actually required (n / 5e4) (divisible) * 5e4 power * n% 5e4 power, which is provided N = 5e4, then n = q * N + r, q = n / N, r = n% N

So that we can (1) obtained in the respective F O (n),

 1 #include<cstdio>
 2 typedef long long ll; 
 3 const int N=5e4,md=998244353;
 4 const ll nv17=438914993,aa=736044383,bb=262199973;
 5 typedef long long ll;
 6 ll a[N+11],af[N+11],b[N+11],bf[N+11];
 7 void init(){
 8     a[0]=b[0]=1;
 9     for(int i=1;i<=N;i++){
10         a[i]=a[i-1]*aa;
11         if(a[i]>=md) a[i]%=md;
12         b[i]=b[i-1]*bb;
13         if(b[i]>=md) b[i]%=md;
14     }
15     af[0]=bf[0]=1;
16     for(int i=1;i<=N;i++){
17         af[i]=af[i-1]*a[N];
18         if(af[i]>=md) af[i]%=md;
19         bf[i]=bf[i-1]*b[N];
20         if(bf[i]>=md) bf[i]%=md;
21     }
22 }
23 int main(){
24     init();
25     int q;
26     ll n;
27     while(~scanf("%d%lld",&q,&n)){
28         ll ans=0,fn,m;
29         while(q--){
30             if(n==0) break;
31             m=n;
32             if(m>=md-1) m=m%(md-1)+(md-1);
33             fn=((af[m/N]*a[m%N])%md)-((bf[m/N]*b[m%N])%md);
34             fn=(fn%md+md)%md;
35             fn*=nv17;
36             if(fn>=md) fn%=md;
37             ans^=fn;
38             n=n^(fn*fn);
39         }
40         printf("%lld\n",ans);
41     }
42     return 0;
43 }
Trained, trained, trained,

However, due to data pre-processing on the basis of garlic off the actual running time has not directly set the power matrix fast fast that he can see a few large data which is faster, but we are not affected by the data, learning It is the key to the thing.

In general, this question involves a general term formula for linear recursion of number sequences, quadratic residue, inverse, and block thinking, is a very good question.

Guess you like

Origin www.cnblogs.com/LMCC1108/p/11495231.html