vijosP1371 方程的解

时间:2024-08-21 15:33:32

vijosP1371 方程的解

链接:https://vijos.org/p/1371

【思路】

组合公式+快速幂+高精单精。

求x^x %1000:因为x最大为2^31-1所以用快速幂在O(logx)的时间内求解g。

安排剩下的k个数:C(g-1,k-1) 相当于把g个数划分到k个不可空的集合中的数目,依旧可以看作插挡板。

考虑这类题目我们可以先从简单情况入手写一个能够处理简单数据的代码,然后再考虑优化的问题。

【代码】

 #include<iostream>
using namespace std; typedef long long LL;
struct Bign{
int len,N[];
};
LL pow(int x) {
LL tmp=x,ans=;
while(x) {
if(x&) ans=(ans*tmp)%;
tmp=(tmp*tmp)%;
x>>=;
}
return ans;
} void multi(Bign& a,int x)
{
for(int j=;j<a.len;j++) a.N[j] *= x;
int i=;
while(i<a.len || a.N[i]>) {
a.N[i+] += a.N[i]/;
a.N[i] %= ;
i++; //i++
}
if(a.N[i]) a.len=i+; //判断
else a.len=i;
} void div(Bign& a,int x) {
for(int i=a.len-;i>;i--) { //由高位到低位
a.N[i-] += a.N[i]%x*;
a.N[i] /= x;
}
a.N[]/=x; //最后一位
while(a.N[a.len-]==) a.len--; //删除前导0
} int main() {
int k,x;
cin>>k>>x;
LL g=pow(x); //x^x
g--; k--;
Bign ans; ans.len=,ans.N[]=;
for(int i=;i<=k;i++) {
multi(ans,g-k+i);
div(ans,i);
}
for(int i=ans.len-;i>=;i--) cout<<ans.N[i];
return ;
}