jzoj4015-数列【循环节,数论】
正題
題目鏈接:https://jzoj.net/senior/#contest/show/3011/0
題目大意
給出n,m,a,b,c,x0n,m,a,b,c,x_0n,m,a,b,c,x0?
xi=axi?12+bxi?1+cx_i=ax_{i-1}^2+bx_{i-1}+cxi?=axi?12?+bxi?1?+c
求xn%mx_n\%mxn?%m
解題思路
第一段n≤1e6n\leq 1e6n≤1e6直接O(n)O(n)O(n)暴力做
第二段m≤1e6m\leq 1e6m≤1e6找到一個循環(huán)節(jié)然后在套到n里
第三段:
xi=axi?12+bxi?1+cx_i=ax_{i-1}^2+bx_{i-1}+cxi?=axi?12?+bxi?1?+c
學過二次函數(shù)的對于給出的性質有敏銳的直覺
xi=a(x+b2a)2+4ac?b24ax_i=a(x+\frac{2a})^2+\frac{4ac-b^2}{4a}xi?=a(x+2ab?)2+4a4ac?b2?
4ac=b2?2b?4ac?b2=2b4ac=b^2-2b\Rightarrow 4ac-b^2=2b4ac=b2?2b?4ac?b2=2b
xi=a(x+b2a)2?b2ax_i=a(x+\frac{2a})^2-\frac{2a}xi?=a(x+2ab?)2?2ab?
然后定義k=b2ak=\frac{2a}k=2ab?
xi+k=a(x+k)2x_i+k=a(x+k)^2xi?+k=a(x+k)2
同時乘上aaa
a(xi+k)=(a(x+k))2a(x_i+k)=(a(x+k))^2a(xi?+k)=(a(x+k))2
定義yi=a(xi+k)y_i=a(x_i+k)yi?=a(xi?+k)
那么有yi=yi?12y_i=y_{i-1}^2yi?=yi?12?
即yn=y02ny_n=y_{0}^{2^n}yn?=y02n?
用費馬小可以讓指數(shù)摸上m?1m-1m?1計算出yny_nyn?,然后倒推出xnx_nxn?
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll M=1e6+10; ll n,m,a,b,c,x,fa[M],cir[M],v[M]; void solve1(){for(ll i=1;i<=n;i++)x=(a*x%m*x%m+b*x%m+c)%m;printf("%lld",x); } void solve2(){x%=m;for(ll i=0;i<=m;i++)fa[i]=(a*i%m*i%m+b*i%m+c)%m;ll cnt=0;cir[0]=x;v[x]=1;while(!v[x=fa[x]])cir[++cnt]=x,v[x]=cnt;x=v[x];if(n<=cnt) printf("%lld",cir[n]);else{n-=x;printf("%lld",cir[x+n%(cnt-x+1)]);} } ll power(ll x,ll b,ll p){ll ans=1;while(b){if(b&1) ans=ans*x%p;x=x*x%p;b>>=1;}return ans; } void solve3(){ll z=b/2/a,y=a*(x+z)%m;y=power(y,power(2,n,m-1),m);printf("%lld",(y*power(a,m-2,m)%m-z+m)%m); } int main() {scanf("%lld%lld%lld%lld%lld%lld",&x,&a,&b,&c,&n,&m);x=x%m;a%=m;b%=m;c%=m;if(n<=1e6)solve1();else if(m<=1e6)solve2();else solve3(); } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結
以上是生活随笔為你收集整理的jzoj4015-数列【循环节,数论】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蚕丛及鱼凫指什么 蚕丛及鱼凫原文和译文
- 下一篇: jzoj4016-圈地为王【状压,bfs