UPC8428 Grid VI

Problem s: Grid VI

Time limit: 1 Sec   Memory Limit: 128 MB
submit: 8   Resolution: 4
[ submit ] [ state ] [proposition man: ADMIN ]

Title Description

A city street grid-like form, the lower left corner coordinates A (0, 0), the coordinates of the upper right corner of B (n, m), where n> = m. Now from A (0, 0) point of view, or only just above the front-right to walk along the street, and not a straight line through the points shown in the upper left, i.e., any route of the point (x, y) must meet x> = y, Will these premises, arrival B (n, m) how many moves.

 

Entry

Only one line containing two integers n and m, represent the size of a city block.

 

Export

Only a whole number and a line feed / carriage return, represents the total number of different schemes.

 

Sample input

6 6

Sample Output

132

 

prompt

100% of the data, 1 <= m <= n <= 5 000

 A combination of mathematical topics, the formula is derived as follows.

 

This question but it is clear that require high precision and high precision multiplication division, but because I'm lazy and do not want to write high-precision division, so the thought of a prime factor decomposition method, the division will be converted into high-precision subtraction prime factor to index do.

So only need to use high-precision multiplication process in the last answer when the answer will come out to deal with, the measured running very fast, much faster than the average high-precision division process.

 

AC code is as follows

#include <bits/stdc++.h>
#define rint register int
typedef long long ll;
using namespace std;
const int N=5e3;
const int mod=1e8;
struct bign
{
    ll val[1000];
    int len;
    bign()
    {
        memset(val,0,sizeof val);
    }
    bign operator *(const bign &t)const
    {
        bign res;
        for(rint i=0; i<len; i++)
            for(rint j=0; j<t.len; j++)
            {
                res.val[i+j]+=val[i]*t.val[j];
                res.val[i+j+1]+=res.val[i+j]/mod;
                res.val[i+j]%=mod;
            }
        res.len=len+t.len;
        if(res.val[res.len-1]==0)res.len--;
        return res;
    }
};
bign transbign(ll x)
{
    int j=0;
    bign res;
    while(x)
    {
        res.val[j++]=x;
        x/=mod;
    }
    res.len=j;
    return res;
}
void write(bign x)
{
    int i=x.len;
    printf("%lld",x.val[--i]);
    while(i)printf("%08lld",x.val[--i]);
    puts("");
}
int prime[2*N+5],cnt;
bool vis[2*N+5];
void erla()
{
    for(int i=2; i<=2*N; i++)
    {
        if(!vis[i])prime[++cnt]=i;
        for(int j=1; j<=cnt&&prime[j]*i<=2*N; j++)
        {
            vis[i*prime[j]]=true;
            if(i%prime[j]==0)break;
        }
    }
}
bign qpow(bign a,ll b)
{
    bign ans;
    ans.val[0]=1;ans.len=1;
    while(b)
    {
        if(b&1)ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}
int up[N*2],down[N*2];
bign ans;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    erla();
    int n,m;
    cin>>n>>m;
    for(int i=n+2; i<=n+m; i++)
    {
        int k=i;
        for(int j=1; j<=cnt&&prime[j]<=k; j++)
        {
            int p=prime[j];
            while(k%p==0)
            {
                up[p]++;
                k/=p;
            }
        }
    }
    int k=n-m+1;
    for(int j=1; j<=cnt&&prime[j]<=k; j++)
    {
        int p=prime[j];
        while(k%p==0)
        {
            up[p]++;
            k/=p;
        }
    }
    for(int i=2; i<=m; i++)
    {
        int k=i;
        for(int j=1; j<=cnt&&prime[j]<=k; j++)
        {
            int p=prime[j];
            while(k%p==0)
            {
                down[p]++;
                k/=p;
            }
        }
    }
    bign t;
    ans.val[0]=1;ans.len=1;
    for(int i=1;i<=cnt;i++)
    {
        int p=prime[i];
        int c=up[p]-down[p];
        if(c==0)continue;
        //cout<<p<<" "<<up[p]<<" "<<down[p]<<endl;
        t=transbign(p);
        t=qpow(t,c);
        ans=ans*t;
    }//cout<<ans.len<<endl;
    write(ans);
    return 0;
}

 

 

Guess you like

Origin www.cnblogs.com/liuquanxu/p/11367774.html