省SD2017 D HEX【乘法逆元+排列+转化】

来源:互联网 发布:linux下端口扫描 编辑:程序博客网 时间:2024/06/10 11:07

HEX

Time Limit: 4 Sec Memory Limit: 128 MB
Submit: 6 Solved: 4
[Submit][Status][Discuss]
Description

On a plain of hexagonal grid, we define a step as one move from the current grid to the lower/lower-left/lower-right grid. For example, we can move from (1,1) to (2,1), (2,2) or (3,2).
In the following graph we give a demonstrate of how this coordinate system works.
Your task is to calculate how many possible ways can you get to grid(A,B) from gird(1,1), where A and B represent the grid is on the B-th position of the A-th line.

Input

For each test case, two integers A (1<=A<=100000) and B (1<=B<=A) are given in a line, process till the end of file, the number of test cases is around 1200.

Output

For each case output one integer in a line, the number of ways to get to the destination MOD 1000000007.

Sample Input

1 1
3 2
100000 100000
Sample Output

1
3
1
HINT

Source

山东省第八届ACM程序设计大赛2017.5.7

#include<iostream>#include<cstdio>using namespace std;#define ll long long int #define mod 1000000007ll i, x, y, a, b, c, ans;ll p[112345];ll n[112345];ll exgcd(ll a, ll b, ll &x, ll &y){    if (!b)    {        x = 1, y = 0;        return a;    }    ll r = exgcd(b, a%b, x, y);    ll temp = x;    x = y;    y = temp - a / b*y;    return r;}ll cal(ll a, ll m){    ll ans, x, y;    ll gcd = exgcd(a, m, x, y);    if (1 % gcd)        return -1;    x *= 1 / gcd;    m = abs(m);    ans = x%m;    if (ans < 0)        ans += m;    return ans;}int main(){    p[0] = 1;    n[0] = cal(p[0], mod);    for (i = 1;i < 112345; i++)    {        p[i] = (p[i - 1] * i) % mod;        n[i] = cal(p[i], mod);    }    while (cin >> x >> y)    {        ans = c = 0;        a = x - y;        b = x - a - 1;        while (~a&&~b)        {            ans = (ans + p[a + b + c] * n[a] % mod*n[b] % mod*n[c] % mod) % mod;            a--, b--, c++;        }        cout << ans << endl;    }}//ll x, y;//ll C(ll n,ll m)//{//  ll ans = 1;//  for (int i = m+1; i <= n; i++)//  {//      ans *= i;//      ans %= MOD;//  }//  for (int i = 1; i <= n - m; i++)//  {//      ans /=i;//      ans %= MOD;//  }//  return (ans + MOD) % MOD;//}//int main()//{//  while (cin >> x >> y)//  {//      x = x - y + 1;//      x--;//      y--;//      ll l, s, r;//向左、向下、向右//      ll answer = 1;//      if (x == 0 || y == 0)//      {//          cout << "1" << endl;//          continue;//      }//      for (int i = 0; i <= x; i++)//      {//          l = i;//          s = x - i;//          r = y - s;//          answer += (C(x, i)*C(y , r)) % MOD;//          answer %= MOD;//      }//      answer += MOD;//      answer %= MOD;//      cout << answer << endl;//  }//  return 0;//}
原创粉丝点击