CodeVS2505 上学路线
生活随笔
收集整理的這篇文章主要介紹了
CodeVS2505 上学路线
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
鏈接
http://codevs.cn/problem/2505/
題解
根據結論,我們要求的是
Cn?1n+m?2這很容易….但,這道題是高精度!
這讓人很不爽,首先想到的是直接套用組合數公式然后高精度乘法+高精度除法。什么?高精除?貌似想切下一題了….
不慌,易知組合數一定是整數,所以我們可以約分。但是極端數據20000*20000,如果分子分母約分的話是 O(n2) 的,會T。
于是我們分解質因數,那就要先篩素數。
把分子分解質因數之后,拿分母分解的質因數去約分。這里我用的根號的質因數分解,然后二分找到最后一個素數(畫蛇添足)。
這樣的話復雜度就很低了。
那位29ms的大佬是什么鬼...
代碼
//組合數+高精 #include <cstdio> #include <algorithm> #define maxl 2000 #define maxn 50000 #define ya 100000000ll #define ll long long using namespace std; struct bignum {ll num[maxl], len;bignum(){for(ll i=0;i<maxl;i++)num[i]=0;len=0;}ll& operator[](ll x){return num[x];}void show(){printf("%lld",num[len]);for(ll i=len-1;i>0;i--){ll x=num[i];for(ll j=ya/10;j and num[i]<j;j/=10)putchar(48);printf("%lld",x);}} }ans; ll n, m, list[maxn], tmp[maxn] ,prime[maxn], q[maxn], mark[maxn], N, M; inline void operator*=(bignum &a, ll b) {ll i;for(i=1;i<=a.len;i++)a[i]*=b;for(i=1;i<=a.len;i++)a[i+1]+=a[i]/ya,a[i]%=ya;if(a[a.len+1])a.len++; } void shai() {ll i, j;for(i=2;i<=N;i++){if(!mark[i])prime[++prime[0]]=i;for(j=1;j<=prime[0] and i*prime[j]<N;j++){mark[i*prime[j]]=1;if(i%prime[j]==0)break;}} } void resolve(ll x, ll d) {ll i, l, r, mid;for(i=1;prime[i]*prime[i]<=x;i++)for(;x%prime[i]==0;x/=prime[i])q[i]+=d;if(x==1)return;for(l=i,r=prime[0],mid=(l+r+1)>>1;l<r;mid=(l+r+1)>>1){if(prime[mid]>x)r=mid-1;else l=mid;}q[l]+=d; } int main() {ll i, j, t;scanf("%lld%lld",&n,&m);N=n+m-2, M=min(n-1,m-1);shai();for(i=N-M+1;i<=N;i++)resolve(i,1);for(i=1;i<=M;i++)resolve(i,-1);ans.len=ans[1]=1;for(i=1;i<=prime[0];i++){for(j=1,t=1;j<=q[i];j++){if(t*prime[i]>ya){ans*=t;t=1;}else t*=prime[i];}if(t>1)ans*=t;}ans.show();return 0; }總結
以上是生活随笔為你收集整理的CodeVS2505 上学路线的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 头条号权重高有什么优势?头条权重在线查询
- 下一篇: 我用 PyTorch 复现了 LeNet