题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5895
转载链接:http://blog.csdn.net/viscu/article/details/52595126
知识点链接:http://blog.csdn.net/acdreamers/article/details/8236942
题意:就是求一个公式
个人感想:
今天补补我没看过的题,我一拿到题,然后拆分一下,我想,不就矩阵快速幂吗,对于每个 f[i]^2 求一个快速幂,然后我看了一下n*y,这个数据<=10^12次方,就算用nlogn求完指数也会超时,…然后我就想不出来了,我考虑过,能不能用矩阵把g【n】一起求出来,然后想了会实在没头绪,- -之后无奈下看了下转载写的题解,… 我曹,这样构造矩阵也可以…,我服…我做这种类型构造有点少啊…所以也没什么感觉,
然后我就觉得这样很简单啊,xjb搞搞就行了… 可是我突然发现…不行啊 应该可以取模才对啊,否则指数无限大啊。。。
我再查了一下取模公式 只有**(a^b)%p ==((a%p)^p)%p**;
但是没用啊。。。。
再百度一下 指数循环节,题解也提到过,看看ACdreamer写的… 没什么解释,就摆了一条公式, 窝尼玛,真牛,我感觉我得去刷刷矩阵幂和 ACdream给的指数循环了… 那里有好多题目…
真的久不做矩阵,我还犯了个错误,原来矩阵是不能交换律的…(⊙o⊙)哦!!!!!,然后测了很久才发现错误…
分析:矩阵快速幂+循环节.
代码:
/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define lson 2*k
#define rson 2*k+1
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
int Scan()//读入整数外挂.
{
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
void Out(int a) //输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
int T;
ll n,y,x,s;
typedef vector<ll> vec;
typedef vector<vec> mat;
int M;
mat mul(mat &A,mat &B)
{
mat C(A.size(),vec(B[0].size()));
for(int i=0;i<A.size();i++)
{
for(int k=0;k<B.size();k++)
{
for(int j=0;j<B[0].size();j++)
{
C[i][j]=(C[i][j]+A[i][k]*B[k][j])%M;
}
}
}
return C;
}
ll pow(mat A,ll n)
{
if(n<=1) return n;
n-=1;
mat B(A.size(),vec(A.size()));
for(int i=0;i<A.size();i++)
{
B[i][i]=1;
}
while(n>0)
{
if(n&1)B=mul(B,A);
A=mul(A,A);
n>>=1;
}
// for(int i=0;i<B.size();i++)
// {
// for(int j=0;j<B[0].size();j++)
// {
// cout<<B[i][j]<<" ";
// }
// cout<<endl;
// }
// cout<<"--->B"<<endl;
mat D(4,vec(4));
D[0][0]=1;
D[3][0]=1;
//
// for(int i=0;i<D.size();i++)
// {
// for(int j=0;j<D.size();j++)
// {
// cout<<D[i][j]<<" ";
// }
// cout<<endl;
// }
// cout<<endl;
D=mul(B,D);
// for(int i=0;i<D.size();i++)
// {
// for(int j=0;j<D.size();j++)
// {
// cout<<D[i][j]<<" ";
// }
// cout<<endl;
// }
// cout<<endl;
return D[3][0]%M;
}
ll ouler(ll x)
{
ll res=x;
for(int i=2;i*i<=x;i++)
{
if(x%i==0)
{
res=res/i*(i-1);
while(x%i==0) x/=i;
}
}
if(x>1) res=res/x*(x-1);
return res;
}
ll qmod(ll a,ll n,ll mod)
{
ll res=1;
while(n)
{
if(n&1)res=(res*a)%mod;
a=(a*a)%mod;
n>>=1;
}
return res%mod;
}
void solve()
{
mat A(4,vec(4));
A[0][0]=4;A[0][1]=4;A[0][2]=1;A[0][3]=0;
A[1][0]=2;A[1][1]=1;A[1][2]=0;A[1][3]=0;
A[2][0]=1;A[2][1]=0;A[2][2]=0;A[2][3]=0;
A[3][0]=4;A[3][1]=4;A[3][2]=1;A[3][3]=1;
ll zhi=pow(A,n*y)%M+M;
printf("%I64d\n",qmod(x,zhi,s+1));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("coco.txt","r",stdin);
freopen("lala.txt","w",stdout);
#endif
scanf("%d",&T);
while(T--)
{
scanf("%I64d%I64d%I64d%I64d",&n,&y,&x,&s);
M=ouler(s+1);
solve();
}
return 0;
}