jzoj 1344. 方程的解 (Standard IO)&&洛谷1771

Description
  佳佳碰到了一個難題,請你來幫忙解決。 對於不定方程a1+a2+……+ak-1+ak=g(x),其中k>=2且k∈N*,x是正整數,g(x)=xx mod 1000(即xx除以1000的餘數),x,k是給定的數。我們要求的是這個不定方程的正整數解組數。   
  舉例來說,當k=3,x=2時,分別爲(a1,a2,a3)=(2,1,1),(1,2,1),(1,1,2).
Input
  輸入文件有且只有一行,爲用空格隔開的兩個正整數,依次爲k,x。
Output
  輸出文件有且只有一行,爲方程的正整數解組數。
Sample Input
3 2
Sample Output
3
Data Constraint
【數據範圍】
對於40%的數據,ans<=1016;
對於100%的數據,k<=100,x<=231-1,k<=g(x)。

//written by zzy

題目大意:

求方程sum(a1…ak)=xx%1000的解的個數

題解:

對於g(x)用快速冪求
考慮解得個數
令g(x)=n,將n拆成n個1,因爲ai>0,所以即等價於n個球中放入k個盤裏,盤不能爲空。
ans=C(k-1,n-1)(組合數)
隔板法即證明:
n個球中放入k個盤裏,盤不能爲空。
放法爲C(k-1,n-1)
例:n=4,k=2
X X X X(球)
1 2 3(板)
即在三個板子裏挑1個插入
方案數爲C(1,3)
(參見組合數的定義C(m,n)等於從1…n中選出m個的數的方案數 等於n!/(m!(n-m)!) )
那麼考慮一般情況
即在n-1個板子裏挑k-1個插入
方案數爲C(k-1,n-1)
證畢。
至於如何求C
將n!和m!,(n-m)!分別分解質因數
冪相減,跑遍高精乘即可。

#include<bits/stdc++.h>
#define Mod 1000
#define N 1005
#define M 1000

using namespace std;

int num,k,x,i,j,n;
int a[N],p[N],ans[M];
bool b[N];

long long g(long long s)
{
	if (s==1) return x;
	long long ss=g(s/2)%Mod;
	if (s&1) return (((ss*ss)%Mod)*x)%Mod;
	else return (ss*ss)%Mod;
}

void chen(int x)
{
	long long g=0,t;
	for (int i=M;i>=1;i--)
	{
		if (i<M&&ans[i+1]==0) break; 
		t=ans[i];
		ans[i]=(t*x+g)%1000000000;
		g=(t*x+g)/1000000000;
	}
}

int main()
{
	scanf("%d%d",&k,&x);
	k--;
	n=g(x); n--;
	memset(b,true,sizeof(b));
	for (i=2;i<=n;i++)
	{
		if (b[i])
		{
			num++; a[num]=i;
			for (j=1;j<=n/i;j++)
			 b[i*j]=false;
		}
	}
	for (i=1;i<=num;i++) {
	    x=a[i];
		while (x<=n) {
			p[i]+=n/x; x*=a[i];
		}
		x=a[i];
		while (x<=k) {
			p[i]-=k/x; x*=a[i];
		}
		x=a[i];
		while (x<=n-k) {
			p[i]-=(n-k)/x; x*=a[i];
		}
	}
	ans[M]=1;
	for (i=1;i<=num;i++)
	 for (j=1;j<=p[i];j++)
		chen(a[i]);
    i=1;
	while (ans[i]==0&&i<=M) i++; 
	printf("%d",ans[i]);
	for (j=i+1;j<=M;j++) {
		x=ans[j];
		if (x<100000000) printf("0");
		if (x<10000000) printf("0");
		if (x<1000000) printf("0");
		if (x<100000) printf("0");
		if (x<10000) printf("0");
		if (x<1000) printf("0");
		if (x<100) printf("0");
		if (x<10) printf("0");
	    printf("%d",ans[j]);
	}
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章