LOJ6440 万能欧几里得

Link

Solution

甩链就跑

Code

注意几个边界的特判。

#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=(a),_ed=(b);i<=_ed;++i)
#define DREP(i,a,b) for(int i=(a),_ed=(b);i>=_ed;--i)
typedef long long ll;
inline ll read(){
    register ll x=0,f=1;register char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^'0');ch=getchar();}
    return f?x:-x;
}

const int N=21,mod=998244353;
int _;ll p,q,r,l;
inline void inc(int &x,int y){x=x+y<mod?x+y:x+y-mod;}
inline ll div(ll n,ll a,ll b,ll c){return ((__int128)a*n+b)/c;}

struct matrix{
    int x[N][N];
    inline int* operator[](const int &a){return x[a];}
    inline const int* operator[](const int &a)const{return x[a];}
    inline matrix(int c=0){REP(i,1,_)REP(j,1,_)x[i][j]=(i==j)*c;}
    inline matrix operator+(const matrix& t){
		matrix res(0);
		REP(i,1,_)REP(j,1,_)res[i][j]=(x[i][j]+t[i][j])%mod;
		return res;
    }
    inline matrix operator*(const matrix &t){
		matrix res(0);
		REP(k,1,_)REP(i,1,_)REP(j,1,_)inc(res[i][j],1ll*x[i][k]*t[k][j]%mod);
		return res;
    }
    inline matrix operator^(ll n){
		matrix ans(1),bas=(*this);
		for(;n;n>>=1,bas=bas*bas)if(n&1)ans=ans*bas;
		return ans;
    }
    inline void print(){
		REP(i,1,_)REP(j,1,_)printf("%d%c",x[i][j],j==_?'\n':' ');
    }
}A,B;

struct node{
    ll U,R;
    matrix A,B,S;
    inline node():U(0),R(0),A(1),B(1),S(0){}
    inline node operator+(const node &t){
		node res;
		res.U=U+t.U,res.R=R+t.R;
		res.A=A*t.A,res.B=B*t.B;
		res.S=S+A*t.S*B;
		return res;
    }
    inline node operator^(ll n){
		node ans,bas=(*this);
		for(;n;n>>=1,bas=bas+bas)if(n&1)ans=ans+bas;
		return ans;
    }
};

inline node solve(ll n,ll a,ll b,ll c,node A,node B){
    if(!n)return node();
    b%=c;
    if(!a)return (A^(b/c))+(B^n);
    if(a>=c)return solve(n,a%c,b,c,A,(A^(a/c))+B);
    ll m=div(n,a,b,c),cnt=n-div(m,c,-b-1,a);
    if(!m)return B^n;
    return (B^((c-b-1)/a))+A+solve(m-1,c,c-b-1,a,B,A)+(B^(cnt));
}

int main(){
    // freopen("in.in","r",stdin);
    p=read(),q=read(),r=read(),l=read(),_=read();
    REP(i,1,_)REP(j,1,_)A[i][j]=read();
    REP(i,1,_)REP(j,1,_)B[i][j]=read();
    node U,R;
    U.U=1,U.B=B;
    R.R=1,R.A=A,R.S=A;
    node ans=(U^(r/q))+solve(l,p,r,q,U,R);
    ans.S.print();
    return 0;
}
posted @ 2020-03-04 20:44  Fruitea  阅读(338)  评论(0编辑  收藏  举报