1. 程式人生 > 其它 >重定向 高精度:加減乘除取模數(from winterstain)

重定向 高精度:加減乘除取模數(from winterstain)

const int WR=1010,bse=10000;
struct BigNum
{
int num[WR],len;
void clr()//陣列內部清空
{
memset(num,0,sizeof(num));len=0;
}
void ipt(int x){clr();num[++len]=x;//清空然後在num裡面加上一個
//元素 ,轉高精度數
}
BigNum operator+(const BigNum&b)const// last---b.
{
BigNum res;
res.clr();
res.len=max(len,b.len)+5;//??
for(int i=1;i<=res.len;i++)
{
res.num[i]
+=num[i]+b.num[i]; res.num[i+1]+=res.num[i]/bse;//一萬進位制?! res.num[i]=res.num[i]%bse; } for(int i=1;i<=res.len;i++) { res.num[i+1]+=res.num[i]/bse; res.num[i+1]%=bse; } while(res.len&& !res.num[res.len])res.len--;//開提前量 //可以不用再擔心我還要不要進位的問題,got it! return res; } BigNum operator-(const BigNum &b)const
{ BigNum res; res.clr(); res.len=max(len,b.len)+5; for(int i=1;i<=res.len;i++) { res.num[i]+=num[i]-b.num[i]; if(res.num[i]<0) { res.num[i]+=bse; res.num[i+1]--; } res.num[i]%=bse; } while(res.len&& !res.num[res.len])res.len--; return res; } BigNum operator*(const BigNum&b)const { BigNum res; res.clr(); res.len
=b.len+len+5; for(int i=1;i<=len;i++) { for(int j=1;j<=b.len;j++) { res.num[i+j-1]+=num[i]*b.num[j]; res.num[i+j]+=res.num[i+j-1]/bse; res.num[i+j-1]%=bse; } } for(int i=1;i<=res.len;i++) res.num[i+1]+=res.num[i]/bse,res.num[i]%=bse; while(res.len&& !res.num[res.len])res.len--; return res; } BigNum operator/(const ll &b)const//const裡面是右邊的引數是嗎? { BigNum res; res.clr(); res.len=len+5; ll bin=0; for(int i=len;i>=1;i--)//從被除數最高位開始 { res.num[i]=(bin*bse+num[i])/b;//商數 bin=(bin*bse+num[i])%b;//餘數 } while(res.len&&!res.num[res.len])res.len--; return res; } long long operator%(const ll &b)const { ll res=0;// 高精度取模 for(int i=len;i>=1;i--) { res=(res*bse+num[i])%b; } return res; } void print() { chu("%d",num[len]); for(int i=len-1;i>=1;i--) { printf("%04d",num[i]); } } }; long long t; ll n,k; BigNum quick_pow(ll a,ll b) { BigNum base,ans; base.ipt(a),ans.ipt(1); while(b>0) { if(b&1)ans=ans*base; b>>=1; base=base*base; } return ans; } ll gcd(ll a,ll b) { if(!b)return a; return gcd(b,a%b); } int main() { t=re(); while(t--) { n=re(),k=re(); if(n>k) { chu("0 1\n"); continue; } BigNum t; t.ipt(k-n+1);//轉成高精度吧? ll x=k-n+1;//乘以的係數 BigNum up,dn; up.clr(),dn.clr(); up=(quick_pow(k+1,n-1)*t);//k+1^(n-1) dn=(quick_pow(k,n));//除以k^n ll gd=dn%x;//為什麼把分母取模數 gd=gcd(x,gd); //約分用的 up=up/gd;up.print();//分子 putchar(' '); dn=dn/gd;dn.print();//分母 putchar('\n'); } return 0; }