题目链接:点这里!!!!!!
题意:
Lcomyn 是个很厉害的选手,除了喜欢写17kb+的代码题,偶尔还会写数学题.他找到了一个数列: fn=⎩⎨⎧1,ab,abfn−1cfn−2,n=1n=2otherwise 他给了你几个数:n,a,b,c,你需要告诉他fn模p后的数值.
第一行一个数T,为测试数据组数. 每组数据一行,一行五个正整数,按顺序为n,a,b,c,p. 1≤T≤10,1≤n≤1018,1≤a,b,c≤109,p是质数且p≤109+7.
对每组数据输出一行一个数,输出fn对p取模后的数值.
1 5 3 3 3 233
190
题解:
1、我们对fn 取loga,假定取log之后是gn。g1=0,g2=b,gn=b+cg(n-1)+g(n-2)
2、针对gn我们可以利用矩阵快速幂求出,时间复杂度O(log(n))
3、注意我们这里gn求出来的是指数,所以需要求出p的欧拉函数,又因为p是质数,所以欧拉函数为p-1,模的时候模p-1。
4、求出gn,再用快速幂求出a^(gn)%p,得到最后的答案。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<sstream> #include<algorithm> #include<vector> #include<bitset> #include<set> #include<queue> #include<stack> #include<map> #include<cstdlib> #include<cmath> #define PI 2*asin(1.0) #define LL long long #define pb push_back #define pa pair<int,int> #define clr(a,b) memset(a,b,sizeof(a)) #define lson lr<<1,l,mid #define rson lr<<1|1,mid+1,r #define bug(x) printf("%d++++++++++++++++++++%d\n",x,x) #define key_value ch[ch[root][1]][0] const int MOD = 1000000007; const int N = 1e3+15; const int maxn = 5e5+1000; const int letter = 130; const int INF = 1e17; const double pi=acos(-1.0); const double eps=1e-8; using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } char a[N]; int vis[N]; int main(){ int z=1,f=0,n=0,p=1,cnt=0; int max1=0,min1=0; gets(a); int len=strlen(a); for(int i=0;i<len;i++){ if(a[i]=='-') f++,vis[cnt++]=-1; else if(a[i]=='+') z++,vis[cnt++]=1; } for(int i=len-1;a[i]>='0'&&a[i]<='9'&&i>=0;i--) n+=p*(a[i]-'0'),p*=10; max1=z*n-f,min1=z-f*n; if(!(min1<=n&&n<=max1)){ puts("Impossible"); return 0; } puts("Possible"); int ff,zz; for(zz=z*n;zz>=z;zz--){ ff=zz-n; if(f<=ff&&ff<=f*n) break; } int zd=zz/z,zm=zz%z; int fd,fm; if(f) fd=ff/f,fm=ff%f; int flag=0; if(zm) flag=1,zm--; printf("%d ",zd+flag); for(int i=0;i<cnt;i++){ if(vis[i]==1){ flag=0; if(zm)flag=1,zm--; printf("+ %d ",zd+flag); } else { flag=0; if(fm) flag=1,fm--; printf("- %d ",fd+flag); } } printf("= %d\n",n); return 0; } /* ? + ? - ? - ? - ? = 100 ? + ? - ? - ? - ? - ? - ? = 10 */