ZJNU 1228 - 矩陣構造——高階 (矩陣快速冪、構造)
阿新 • • 發佈:2021-08-13
題面
要求構造下面的矩陣:
- 矩陣的大小為\(S(n)*S(n)\);
- \(S(n)\)表示Fibonacci數列前\(n\)項和對\(m\)取模之後的值,即\(S(n)=(F_1+F_2+…+F_n)%m\);
- 矩陣僅由\(-1,0,1\)三種值構成
- 矩陣每一行每一列的和都不相同
\(F_1=F_2=1\);
給定\(n\)和\(m\),輸出這樣一個矩陣。
思路
做法應當有很多種,但由於沒有SPJ所以輸出必須得與樣例的想法相同(可惡)
首先就是斐波那契前\(n\)項字首和對\(m\)取模,矩陣快速冪求出即可
記接下來的\(n\)就是構造的矩陣邊長
稍微小範圍打表可得\(n\)為奇數時或者\(n=0\)時不存在解
否則根據以下方式構造(難講)
\(n=2\)時:
\(n=4\)時:
\(n=6\)時:
\(n=8\)時:
#include<bits/stdc++.h> #define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0) #define multiCase int T;cin>>T;for(int t=1;t<=T;t++) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i<(b);i++) #define per(i,a,b) for(int i=(a);i>=(b);i--) #define perr(i,a,b) for(int i=(a);i>(b);i--) #define all(a) (a).begin(),(a).end() #define SUM(a) accumulate(all(a),0LL) #define MIN(a) (*min_element(all(a))) #define MAX(a) (*max_element(all(a))) #define mst(a,b) memset(a,b,sizeof(a)) #define pb push_back #define eb emplace_back #define fi first #define se second using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; const int INF=0x3f3f3f3f; const ll LINF=0x3f3f3f3f3f3f3f3f; const double eps=1e-12; const double PI=acos(-1.0); ll mod=998244353; const int dx[8]={0,1,0,-1,1,1,-1,-1},dy[8]={1,0,-1,0,1,-1,1,-1}; void debug(){cerr<<'\n';}template<typename T,typename... Args>void debug(T x,Args... args){cerr<<"[ "<<x<< " ] , ";debug(args...);} mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count()); ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);} ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);} ll qmul(ll a,ll b){ll r=0;while(b){if(b&1)r=(r+a)%mod;b>>=1;a=(a+a)%mod;}return r;} ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;} ll qpow(ll a,ll n,ll p){ll r=1;while(n){if(n&1)r=(r*a)%p;n>>=1;a=(a*a)%p;}return r;} struct quickpow_fibonacci { struct matrix { ll n,m,data[3][3]; void init() { for(int i=0;i<n;i++) data[i][i]=1; } }; matrix multi(matrix &a,matrix &b) { matrix t; t.n=a.n; t.m=b.m; for(int i=0;i<t.n;i++) { for(int j=0;j<t.m;j++) t.data[i][j]=0; } for(int i=0;i<a.n;i++) { for(int k=0;k<a.m;k++) { if(a.data[i][k]>0) { for(int j=0;j<b.m;j++) t.data[i][j]=(t.data[i][j]+a.data[i][k]*b.data[k][j]%mod)%mod; } } } return t; } matrix fast_mod(matrix &a,ll n) { matrix r; r.n=a.n; r.m=a.m; memset(r.data,0,sizeof(r.data)); r.init(); while(n>0) { if(n&1) r=multi(r,a); a=multi(a,a); n>>=1; } return r; } ll solve(ll n) { matrix a,b; a.n=1; a.m=3; a.data[0][0]=1; a.data[0][1]=1; a.data[0][2]=1; b.n=3; b.m=3; b.data[0][0]=0; b.data[0][1]=1; b.data[0][2]=0; b.data[1][0]=1; b.data[1][1]=1; b.data[1][2]=1; b.data[2][0]=0; b.data[2][1]=0; b.data[2][2]=1; b=fast_mod(b,n-1); return multi(a,b).data[0][2]; } }f; int ans[205][205]; void solve() { ll n; cin>>n>>mod; n=f.solve(n); if(n==0||n%2) { cout<<"No\n"; return; } cout<<"Yes\n"; rep(i,1,n/2) { rep(j,1,n-i+1) ans[i][j]=-1; rep(j,n-i+2,n) ans[i][j]=0; } rep(i,n/2+1,n) { rep(j,1,n+1-i) ans[i][j]=0; rep(j,n+1-i+1,n) ans[i][j]=1; } per(j,n,1) per(i,n,1) cout<<-ans[i][j]<<(i==1?'\n':' '); // 輸出方式改一改對正確性不影響 } int main() { closeSync; //multiCase { solve(); } return 0; }