洛谷1771 方程的解
阿新 • • 發佈:2019-01-31
題目描述
佳佳碰到了一個難題,請你來幫忙解決。
對於不定方程a1+a2+…+ak-1+ak=g(x),其中k≥2且k∈N,x是正整數,g(x)=x^x mod
1000(即x^x除以1000的餘數),x,k是給定的數。我們要求的是這個不定方程的正整數解組數。舉例來說,當k=3,x=2時,分別為(a1,a2,a3)=(2,1,1)’(1,2,1),(1,1,2)。 輸入輸出格式 輸入格式:
輸入檔案equation.in有且只有一行,為用空格隔開的兩個正整數,依次為k,x。
輸出格式:
輸出檔案equation.out有且只有一行,為方程的正整數解組數。
快速冪求出g(x)。
考慮裸的dp方程,dp[i][j]表示i個數和為j的方案數,dp[i][j]=Σdp[i-1][i-1…j-1],時間複雜度為O(k*mod^2)。
注意到邊界條件dp[0][0]=1,其他所有值都由它推得,從刷表的角度考慮,dp[i][j]每次一定走到dp[i+1][j+x],最終要走到dp[k][g]。不妨看成要走k步,每一步可以走一個或一個以上的格子,最後總共要走g個格子,問方法總數。
這樣就變成了計數問題,即要在(g-1)個間隔中選出(k-1)個,答案是c(g-1,k-1)。
注意使用高精度。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
const int bit=10000;
const int mod=1000;
struct NUM
{
int a[100],l;
NUM operator + (const NUM & x)
{
NUM ret;
ret.a[1]=0;
for (int i=1;i<=l||i<=x.l;i++)
{
ret.a[i]+=a[i]+x.a[i];
ret.a[i+1 ]=ret.a[i]/bit;
ret.a[i]%=bit;
}
ret.l=max(l,x.l);
if (ret.a[ret.l+1]) ret.l++;
return ret;
}
void out()
{
int i,j,k,x,y,z;
printf("%d",a[l]);
for (i=l-1;i;i--)
{
if (a[i]<10) printf("000");
else
{
if (a[i]<100) printf("00");
else
{
if (a[i]<1000) printf("0");
}
}
printf("%d",a[i]);
}
printf("\n");
}
}c[1010][110];
int pw(int x)
{
int base=x%mod,ans=1;
for (;x;x>>=1,base=(base*base)%mod)
if (x&1) ans=(ans*base)%mod;
return ans;
}
int main()
{
int i,j,k,m,n,p,q,x,y,z;
scanf("%d%d",&k,&x);
m=pw(x);
for (i=0;i<m;i++)
c[i][0].a[1]=c[i][0].l=1;
for (i=1;i<m;i++)
for (j=1;j<k;j++)
c[i][j]=c[i-1][j-1]+c[i-1][j];
c[m-1][k-1].out();
}