正题
题目链接:https://jzoj.net/senior/#contest/show/3011/0
题目大意
给出
求
解题思路
第一段
直接
暴力做
第二段
找到一个循环节然后在套到n里
第三段:
学过二次函数的对于给出的性质有敏锐的直觉
然后定义
同时乘上
定义
那么有
即
用费马小可以让指数摸上 计算出 ,然后倒推出
#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();
}