zoukankan      html  css  js  c++  java
  • CF1106F Lunar New Year and a Recursive Sequence

    又傻掉了呢
    看到连乘显然直接转原根变成线性齐次递推式。
    矩阵乘法求一发。
    然后分析一下发现是个x^k=m的形式。
    按照套路解一下高次方程就好了。
    需要用到exgcd和bsgs。

    #include<iostream>
    #include<cctype>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<ctime>
    #include<map>
    #include<cstdlib>
    #include<algorithm>
    #define N 120
    #define L 110
    #define eps 1e-7
    #define inf 1e9+7
    #define db double
    #define ll long long
    #define ldb long double
    using namespace std;
    inline ll read()
    {
    	char ch=0;
    	ll x=0,flag=1;
    	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*flag;
    }
    const ll g=3;
    const ll p=998244352;
    const ll mo=998244353;
    struct matrix 
    {
    	ll s[N][N];
    	void clear(){memset(s,0,sizeof(s));}
    };
    matrix operator*(matrix a,matrix b)
    {
    	matrix ans;
    	ans.clear();
    	for(ll i=0;i<=L;i++)
    	  for(ll j=0;j<=L;j++)
    	    for(ll k=0;k<=L;k++)
    	    ans.s[i][j]=(ans.s[i][j]+(a.s[i][k]*b.s[k][j]%p))%p;
    	return ans;
    }
    matrix ksm(matrix x,ll k)
    {
    	matrix ans;
    	ans.clear();
    	for(ll i=0;i<=L;i++)ans.s[i][i]=1;
    	while(k)
    	{
    		if(k&1)ans=ans*x;
    		k>>=1;
    		x=x*x; 
    	}
    	return ans;
    }
    matrix f;
    ll qpow(ll x,ll k)
    {
    	ll ans=1;
    	while(k)
    	{
    		if(k&1)ans=ans*x%mo;
    		k>>=1;
    		x=x*x%mo;
    	}
    	return ans;
    }
    ll X,Y;
    ll exgcd(ll a,ll b)
    {
    	if(!b){X=1,Y=0;return a;}
    	ll d=exgcd(b,a%b);
    	ll t=X;X=Y,Y=t-(a/b)*Y;
    	return d;
    }
    map<ll,ll>S;
    map<ll,ll>::iterator it;
    ll bsgs(ll a,ll n)
    {
    	S.clear();
    	ll x=1,k=1,len=sqrt(mo);
    	for(ll i=0;i<len;i++,x=(x*a)%mo)
    	if(S.find(x)==S.end())S.insert(pair<ll,ll>{x,i});
    	for(ll i=0;i<mo;i+=len,k=(k*x)%mo)
    	{
    		exgcd(k,mo),X=((X%mo+mo)%mo*n)%mo;
    		it=S.find(X);
    		if(it!=S.end())return i+(it->second);
    	}
    	return 0;
    }
    int main()
    {
    	ll k=read();
    	f.clear();
    	for(ll i=1;i<k;i++)f.s[i+1][i]=1;
    	for(ll i=1;i<=k;i++)f.s[k-i+1][k]=read();
    	ll n=read(),m=read();
    	f=ksm(f,n-k);f.s[k][k]=(f.s[k][k]%p+p)%p;
    	ll o=bsgs(g,m),d=exgcd(f.s[k][k],p);
    	if(o%d==0)
    	{
    		X=X%p*(o/d)%p;
    		printf("%lld",qpow(g,(X%p+p)%p));
    	}
    	else printf("-1");
    	return 0;
    }
    
  • 相关阅读:
    【实战】Weblogic xmldecoder反序列化Getshell
    【实战】JBOSS反序列化Getshell
    【实战】Tomcat管理后台Getshell
    【Python】二进制转ASCII码小脚本
    【实战】sqlmap显示有注入却无法爆出库名
    【总结】APP客户端渗透测试
    【总结】Struts2系列漏洞POC小结
    【Python】端口扫描脚本
    2020中国高校计算机大赛 华为云大数据挑战赛--热身赛--爬取天气数据
    2020中国高校计算机大赛 华为云大数据挑战赛--热身赛--赛题分析、数据理解
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/10349300.html
Copyright © 2011-2022 走看看