zoukankan      html  css  js  c++  java
  • ZJNU 1228

    ZJNU 1228 - 矩阵构造——高级

    题面

    要求构造下面的矩阵:

    1. 矩阵的大小为(S(n)*S(n))
    2. (S(n))​表示Fibonacci数列前(n)​项和对(m)​取模之后的值,即(S(n)=(F_1+F_2+…+F_n)%m)​;
    3. 矩阵仅由(-1,0,1)三种值构成
    4. 矩阵每一行每一列的和都不相同

    (F_1=F_2=1)​;​

    给定(n)(m),输出这样一个矩阵。


    思路

    做法应当有很多种,但由于没有SPJ所以输出必须得与样例的想法相同(可恶)

    首先就是斐波那契前(n)项前缀和对(m)​取模,矩阵快速幂求出即可

    记接下来的(n)就是构造的矩阵边长

    稍微小范围打表可得(n)为奇数时或者(n=0)​时不存在解

    否则根据以下方式构造(难讲)

    (n=2)时:

    n_2

    (n=4)时:

    n_4

    (n=6)时:

    n_6

    (n=8)时:

    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<<'
    ';}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
    ";
            return;
        }
        cout<<"Yes
    ";
        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?'
    ':' '); // 输出方式改一改对正确性不影响
    }
    int main()
    {
        closeSync;
        //multiCase
        {
            solve();
        }
        return 0;
    }
    

  • 相关阅读:
    (转载)Linux系统中分离线程的使用
    (转载)Vim的几种模式介绍
    (转载)Linux下检查内存泄漏、系统性能的系列工具
    (转载)Linux 僵尸进程与孤儿进程
    (转载)valgrind,好东西,一般人我不告诉他~~ 选项
    (转载)Linux进程组、作业、会话的理解
    Open a file, and then readin a file tcl tk
    save vars and arrays
    itcl class example
    constructor with args tcl tk
  • 原文地址:https://www.cnblogs.com/stelayuri/p/15138487.html
Copyright © 2011-2022 走看看