hdu 5895 Mathematician QSC 指数循环节+矩阵快速幂

Mathematician QSC

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Problem Description

QSC dream of becoming a mathematician, he believes that everything in this world has a mathematical law.

Through unremitting efforts, one day he finally found the QSC sequence, it is a very magical sequence, can be calculated by a series of calculations to predict the results of a course of a semester of a student.

This sequence is such like that, first of all,f(0)=0,f(1)=1,f(n)=f(n−2)+2∗f(n−1)(n≥2)Then the definition of the QSC sequence is g(n)=∑ni=0f(i)2. If we know the birthday of the student is n, the year at the beginning of the semester is y, the course number x and the course total score s, then the forecast mark is xg(n∗y)%(s+1).
QSC sequence published caused a sensation, after a number of students to find out the results of the prediction is very accurate, the shortcoming is the complex calculation. As clever as you are, can you write a program to predict the mark?

Input

First line is an integer T(1≤T≤1000).

The next T lines were given n, y, x, s, respectively.

n、x is 8 bits decimal integer, for example, 00001234.

y is 4 bits decimal integer, for example, 1234.
n、x、y are not negetive.

1≤s≤100000000

Output

For each test case the output is only one integer number ans in a line.

Sample Input

2
20160830 2016 12345678 666
20101010 2014 03030303 333

Sample Output

1
317

Source

2016 ACM/ICPC Asia Regional Shenyang Online

思路:首先求A^B%C=A^(B%phi(C)+phi(C))%C  B>=phi(C)指数循环节;

     然后,求g函数,f(n)显然可以用矩阵快速幂写,g(n)=f(n)*f(n+1)/2;因为/2,模除法,首先想到逆元,然而模不一定是奇数,偶数的情况2无逆元;

   现在怎么处理2,f(n)与f(n+1)必然有一个是偶数,发现除2后的递推式更改为f(n)=6*f(n-1)-f(n-2);

   ps:一个小技巧处理2,mdzz,模的数*2,答案/2;

   详见代码;

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
const int N=1e5+10,M=1e6+1010,inf=1e9+10,mod=1e9+7;
const ll INF=1e18+10;
ll n,x,y,s;
ll m;
struct is
{
    ll a[10][10];
};
is juzhenmul(is a,is b,ll hang ,ll lie,ll mod)
{
    int i,t,j;
    is ans;
    memset(ans.a,0,sizeof(ans.a));
    for(i=1;i<=hang;i++)
    for(t=1;t<=lie;t++)
    for(j=1;j<=lie;j++)
    {
        ans.a[i][t]+=(a.a[i][j]*b.a[j][t]);
        ans.a[i][t]%=mod;
    }
    return ans;
}
is quickpow(is ans,is a,ll x,ll mod)
{
    while(x)
    {
        if(x&1)  ans=juzhenmul(ans,a,2,2,mod);
        a=juzhenmul(a,a,2,2,mod);
        x>>=1;
    }
    return ans;
}
void extend_Euclid(ll a, ll b, ll &x, ll &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return;
    }
    extend_Euclid(b, a % b, x, y);
    ll tmp = x;
    x = y;
    y = tmp - (a / b) * y;
}
ll phi(ll n)
{
    ll i,rea=n;
    for(i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            rea=rea-rea/i;
            while(n%i==0)  n/=i;
        }
    }
    if(n>1)
        rea=rea-rea/n;
    return rea;
}
ll Pow(ll a,ll n,ll mod)
{
    ll ans=1;
    while(n)
    {
        if(n&1)
        {
            ans=ans*a%mod;
        }
        a=a*a%mod;
        n>>=1;
    }
    if(ans==0) ans+=mod;
    return ans;
}
ll getans(ll x,ll mod)
{
    if(x==0)
    return 0;
    if(x==1)
    return 1;
    is ans,base;
    memset(ans.a,0,sizeof(ans.a));
    ans.a[1][1]=1;
    ans.a[2][2]=1;
    base.a[1][1]=0;
    base.a[1][2]=1;
    base.a[2][1]=1;
    base.a[2][2]=2;
    ans=quickpow(ans,base,x-2,mod);
    return (ans.a[2][1]+ans.a[2][2]*2)%mod;
}
ll getans2(ll x,ll mod)
{
    if(x==0)
    return 0;
    if(x==1)
    return 1;
    is ans,base;
    memset(ans.a,0,sizeof(ans.a));
    ans.a[1][1]=1;
    ans.a[2][2]=1;
    base.a[1][1]=6;
    base.a[1][2]=-1;
    base.a[2][1]=1;
    base.a[2][2]=0;
    ans=quickpow(ans,base,x-2,mod);
    return ((((ans.a[1][1]*6-ans.a[2][1])%mod)+mod)%mod);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld%lld",&n,&y,&x,&s);
        ll zhi=n*y;
        m=phi(s+1);
        ll k;
        if(zhi%2==0)
        k=(getans(zhi+1,m)%m)*(getans2(zhi/2,m)%m)%m;
        else
        k=(getans(zhi,m)%m)*(getans2((zhi+1)/2,m)%m)%m;
        ll out=Pow(x,k,s+1);
        printf("%lld\n",out);
    }
    return 0;
}
时间: 2024-08-24 21:37:55

hdu 5895 Mathematician QSC 指数循环节+矩阵快速幂的相关文章

Brute-force Algorithm HDU - 3221(指数循环节 矩阵快速幂)

水题一道 推一下就是 f[n] = f[n - 1] + f[n - 2] 发现n很大 所以用矩阵快速幂就好了 还有P很大  那就指数循环节 一定要注意   这个条件 #include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <cctype> #include <set> #incl

HDU 5895 Mathematician QSC(矩阵乘法+循环节降幂+除法取模小技巧+快速幂)

传送门:HDU 5895 Mathematician QSC 这是一篇很好的题解,我想讲的他基本都讲了http://blog.csdn.net/queuelovestack/article/details/52577212 [分析]一开始想简单了,对于a^x mod p这种形式的直接用欧拉定理的数论定理降幂了 结果可想而知,肯定错,因为题目并没有保证gcd(x,s+1)=1,而欧拉定理的数论定理是明确规定的 所以得另谋出路 那么网上提供了一种指数循环节降幂的方法 具体证明可以自行从网上找一找 有

HDU 5171 GTY&#39;s birthday gift(矩阵快速幂 )

HDU 5171 GTY's birthday gift ( 矩阵快速幂裸题目 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX_SIZE 3 #define MOD 10000007 #define clr( a, b ) memset( a, b, sizeof(a) ) typedef long long LL; struct M

HDU 5895 Mathematician QSC

题目地址 欧拉函数+矩阵快速幂 1 #include<cstdio> 2 #include<algorithm> 3 #include<string.h> 4 #include<queue> 5 #define LL long long 6 using namespace std; 7 const int Nmax=10; 8 LL n,y,x,s,tmp; 9 int mod; 10 int oula_mod; 11 12 struct Matrix 13

HDU 4990 Reading comprehension(找规律+矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4990 Problem Description Read the program below carefully then answer the question. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include<iostream> #include

hdu 2604 Queuing dp找规律 然后矩阵快速幂。坑!!

http://acm.hdu.edu.cn/showproblem.php?pid=2604 这题居然O(9 * L)的dp过不了,TLE,  更重要的是找出规律后,O(n)递推也过不了,TLE,一定要矩阵快速幂.然后立马GG. 用2代表m,1代表f.设dp[i][j][k]表示,在第i位,上一位站了的人是j,这一位站的人是k,的合法情况. 递推过去就是,如果j是1,k是2,那么这一位就只能放一个2,这个时猴dp[i][k][2] += dp[i - 1][j][k]; 其他情况分类下就好,然后

HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)

Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 249    Accepted Submission(s): 140 Problem Description Farmer John likes to play mathematics games with his N cows. Recently, t

HDU 5318 The Goddess Of The Moon (矩阵快速幂)

题目链接:HDU 5318 The Goddess Of The Moon 题意:给出N串字符串,若是一个字符串的后缀与另一个字符串的前缀相同并且长度大于1,就表示这两个字符串是可以相连的,问M个字符串相连不同方案数为多少. 思路: 1.将输入的字符串预处理存入一个矩阵中,mp[i][j]=1说明str[i]与str[j]能相连,反之,则不能相连. 2.str[i]与str[j]能相连 转化为 i点到j点可达,那么就可以得到一个有向图,长度为M的意思就是 两点之间所走的步数为M的不同走法有多少种

(hdu 6030) Happy Necklace 找规律+矩阵快速幂

题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=6030 Problem Description Little Q wants to buy a necklace for his girlfriend. Necklaces are single strings composed of multiple red and blue beads. Little Q desperately wants to impress his girlfriend,