HDU 6442 GuGu Convolution CCPC 2018 网络赛

HDU 6442 GuGu Convolution CCPC 2018 网络赛_第1张图片

HDU 6442 GuGu Convolution CCPC 2018 网络赛_第2张图片

 

题意:

给出两个生成函数,求他们的卷积的第n项的系数。要求输出形如A\sqrt{B}的最简形式。

题解:

首先根据题意可以得出答案就是:HDU 6442 GuGu Convolution CCPC 2018 网络赛_第3张图片

可以如下化简:

HDU 6442 GuGu Convolution CCPC 2018 网络赛_第4张图片

可以类比快速幂的求法:

 

需要注意的是:

由于模数p可能与2不互质,所以运算时对(p*2)取模,求出答案后除以2即可。

由于要带根号的最简形式,所以对B分解因数。

 

代码:

#include
#define N 60010
#define INF 0x3f3f3f3f
#define eps 1e-10
#define pi 3.141592653589793
#define LL long long
#define pb push_back
#define cl clear
#define si size
#define lb lowwer_bound
#define mem(x) memset(x,0,sizeof x)
#define sc(x) scanf("%d",&x)
#define scc(x,y) scanf("%d%d",&x,&y)
#define sccc(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;

vectorv;
bool f[1000];

int ppp(int n)
{
    if(n==1) return 1;
    int res=1;
    for(auto i:v)
    {
        if(n%i==0)
        {
           int num=1;
           while (n%i==0)
           {
               n/=i;
               num++;
               if (num&1) res*=i;
           }
        }
        if (i*i>n) break;
    }
    return res;
}

LL qmi(LL p,LL q,LL n,LL mod,LL B)
{
    LL a=1,b=1,t1,t2;
    while(n)
    {
        if (n&1)
        {
            t1=(a*p+b*q%mod*B)%mod;
            t2=(a*q+b*p)%mod;
            a=t1;b=t2;
        }
        t1=(p*p+q*q%mod*B)%mod;
        t2=(p*q*2)%mod;
        p=t1;q=t2;
        n>>=1;
    }
    return b;
}

int main()
{
    for (int i=2;i<1000;i++) if (!f[i]) { v.push_back(i); for (int j=i+i;j<1000;j+=i) f[j]=1; }
    int T; LL n,A,B,p,ans;
    sc(T);
    while(T--)
    {
        scanf("%I64d%I64d%I64d%I64d",&A,&B,&n,&p);
        p<<=1;
        ans=(qmi(A,1,n,p,B)-qmi(A,-1,n,p,B)+p)%p;
        ans>>=1; p>>=1;
        int k=ppp(B);
        ans=ans*k%p; B=B/k/k;
        printf("1 %I64d %I64d\n",ans,B);
    }
}

 

你可能感兴趣的:(数学)