版权声明:欢迎转载(请附带原链接)ヾ(๑╹◡╹)ノ" https://blog.csdn.net/corsica6/article/details/85097095
传送门:loj138
题解
被标题坑进去,断断续续做了一天。。。确实是“类欧几里得算法”啊(雾。。。
设答案为函数
考虑以下情况:
-
为常量( 或 ),直接拉格朗日插值算出 即可。
-
或 , ,二项式展开一下得到若干 ,迭代求解 即可。
-
不满足上面两种情况( ),把 转成 (设 )。
设 ,则
与 相同, 同样可以插值算出,设分别为多项式 ,减号右边的式子转成:
化成 的形式迭代求解 。
因为这里 是取遍 的,所以具体求解时直接求解 ,返回所有合法的 的值( )
考虑到迭代过程中 ,次数是 的,每层的枚举也最多是 的。
代码
#include<bits/stdc++.h>
#define mem(f,x) memset(f,x,sizeof(f))
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const int mod=1e9+7;
int tk,val[15],tmp[15],C[25][25];
int qa[25],qb[25];
inline void dc(int &x,int y){x-=y;if(x<0) x+=mod;}
inline int dci(int x,int y){x-=y;return x<0?x+mod:x;}
inline void ad(int &x,int y){x+=y;if(x>=mod) x-=mod;}
inline int adi(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int fp(int x,int y)
{
int re=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1) re=(ll)re*x%mod;
return re;
}
struct arr{int g[11][11];}tep;
int g[25],h[25];
struct xs{
int sz,v[25];
inline void mk(int *t)
{
ui i,j,k;mem(g,0);g[0]=1;
for(i=0;i<21;++i){
for(j=i+1;j;--j)
g[j]=dci(g[j-1],(ll)g[j]*i%mod);
g[0]=(mod-(ll)g[0]*i%mod)%mod;
}
for(i=0;i<21;++i){
memcpy(h,g,sizeof(h));
for(j=21;j;--j) ad(h[j-1],(ll)h[j]*i%mod);
for(k=1,j=0;j<i;++j) k=(ll)k*(i-j)%mod;
for(j=i+1;j<21;++j) k=(ll)k*(mod+i-j)%mod;
k=(ll)t[i]*fp(k,mod-2)%mod;
for(j=0;j<21;++j) ad(v[j],(ll)h[j+1]*k%mod);
}
for(sz=21;sz&&(!v[sz]);--sz);
}
inline int cal(ll x)
{
int re=0,bs=1,i;x%=mod;
for(i=0;i<=sz;++i,bs=x*bs%mod) ad(re,(ll)bs*v[i]%mod);
return re;
}
}kda[11],kdb[11];
//a-> i^k
//b-> (i+1)^k-i^k
arr F(int a,int b,int c,ll n)
{
arr re;if(!n) a=0;
int i,j,k,t,x,y,p,q,ip,iq;
if((!a)||(n*a+b<c)){
for(i=0;i<=10;++i){
k=kda[i].cal(n);t=b/c;
for(j=0;i+j<=10;++j,k=(ll)k*t%mod)
re.g[i][j]=k;
}
return re;
}
for(i=0;i<=10;++i) re.g[i][0]=kda[i].cal(n);
if(a>=c || b>=c){
arr nw=F(a%c,b%c,c,n);
p=a/c;q=b/c;
for(i=0;i<=10;++i)
for(j=1;i+j<=10;++j){
k=0;ip=1;
for(x=0;x<=j;++x,ip=(ll)ip*p%mod){
iq=1;
for(y=0;x+y<=j;++y,iq=(ll)iq*q%mod)
ad(k,(ll)ip*iq%mod*(ll)C[j][x]%mod*(ll)C[j-x][y]%mod*(ll)nw.g[i+x][j-x-y]%mod);
}
re.g[i][j]=k;
}
return re;
}
ll m=(n*a+b)/c;
arr nw=F(c,c-b-1,a,m-1);
for(i=0;i<=10;++i)
for(j=1;i+j<=10;++j){
k=(ll)kdb[j].cal(m-1)*kda[i].cal(n)%mod;
for(x=0;x<j;++x){
for(y=0;y<=kda[i].sz;++y){
dc(k,(ll)C[j][x]*kda[i].v[y]%mod*(ll)nw.g[x][y]%mod);
}
}
re.g[i][j]=k;
}
return re;
}
int main(){
int i,j,n,a,b,c,k1,k2;C[0][0]=1;
for(i=1;i<25;++i){
C[i][i]=C[i][0]=1;
for(j=1;j<i;++j) C[i][j]=adi(C[i-1][j-1],C[i-1][j]);
}
for(i=0;i<=10;++i){
a=b=0;
for(j=0;j<=20;++j){
c=fp(j,i);
ad(a,c);ad(b,dci(fp(j+1,i),c));
qa[j]=a;qb[j]=b;
}
kda[i].mk(qa);kdb[i].mk(qb);
}
for(scanf("%d",&tk);tk;--tk){
scanf("%d%d%d%d%d%d",&n,&a,&b,&c,&k1,&k2);
printf("%d\n",F(a,b,c,n).g[k1][k2]);
}
return 0;
}