• Codeforces Round #818 (Div. 2) D - Madoka and The Corruption Scheme


    D. Madoka and The Corruption Scheme

    time limit per test

    1 second

    memory limit per test

    256 megabytes

    input

    standard input

    output

    standard output

    Madoka decided to entrust the organization of a major computer game tournament "OSU"!

    In this tournament, matches are held according to the "Olympic system". In other words, there are 2n2n participants in the tournament, numbered with integers from 11 to 2n2n. There are nn rounds in total in the tournament. In the ii-th round there are 2n−i2n−i matches between two players (one of whom is right, the other is left), after which the winners go further along the tournament grid, and the losing participants are eliminated from the tournament. Herewith, the relative order in the next round does not change. And the winner of the tournament — is the last remaining participant.

    But the smaller the participant's number, the more he will pay Madoka if he wins, so Madoka wants the participant with the lowest number to win. To do this, she can arrange the participants in the first round as she likes, and also determine for each match who will win — the participant on the left or right.

    But Madoka knows that tournament sponsors can change the winner in matches no more than kk times. (That is, if the participant on the left won before the change, then the participant on the right will win after the change, and if the participant on the right won, then the participant on the left will win after the change).

    So, the first image shows the tournament grid that Madoka made, where the red lines denote who should win the match. And the second one shows the tournament grid, after one change in the outcome of the match by sponsors (a match between 11 and 33 players).

    Print the minimum possible number of the winner in the tournament, which Madoka can get regardless of changes in sponsors. But since the answer can be very large, output it modulo 109+7109+7. Note that we need to minimize the answer, and only then take it modulo.

    Input

    The first and the only line contains two integers nn and kk (1≤n≤105,1≤k≤min(2n−1,109)1≤n≤105,1≤k≤min(2n−1,109)) — the number of rounds in the tournament and the number of outcomes that sponsors can change.

    Output

    Print exactly one integer — the minimum number of the winner modulo 109+7109+7

    Examples

    input

    Copy

    1 1
    

    output

    Copy

    2
    

    input

    Copy

    2 1
    

    output

    Copy

    3
    

    input

    Copy

    3 2
    

    output

    Copy

    7
    

    Note

    In the first example, there is only one match between players 11 and 22, so the sponsors can always make player 22 wins.

    The tournament grid from the second example is shown in the picture in the statement.

    1. #include<iostream>
    2. #include<algorithm>
    3. #include<map>
    4. #include<cmath>
    5. #include<cstring>
    6. #include<iomanip>
    7. #include<numeric>
    8. #include<stack>
    9. #include<queue>
    10. #include<set>
    11. #include<string>
    12. #include<vector>
    13. using namespace std;
    14. typedef long long ll;
    15. typedef unsigned long long ull;
    16. const int inf=0x3f3f3f3f,maxn=1e5+5,mod=1e9+7;
    17. int fac[maxn]={1},fac_inv[maxn]={1};//计算组合数要用的,这种是只计算最底层的组合数,就是C_n^i,差不多就是O(n)
    18. int n,k;
    19. void exgcd(int a,int b,ll &x,ll &y)
    20. {
    21. if(!b)
    22. {
    23. x=1;
    24. y=0;
    25. }
    26. else
    27. {
    28. exgcd(b,a%b,y,x);
    29. y-=a/b*x;
    30. }
    31. }
    32. void init()
    33. {
    34. for(int i=1;i<maxn;i++)
    35. {
    36. fac[i]=(ll)fac[i-1]*i%mod;
    37. }
    38. ll x,y;
    39. exgcd(fac[maxn-1],mod,x,y);
    40. fac_inv[maxn-1]=(x%mod+mod)%mod;//这个用exgcd求
    41. for(int i=maxn-2;i>=0;i--)
    42. {
    43. fac_inv[i]=(ll)fac_inv[i+1]*(i+1)%mod;//这样相当于“线性求逆元”了
    44. //这个递推公式的话,写两个式子 t! * inv(t!) ≡1 (mod b)
    45. // (t+1)!*inv((t+1)!)≡1 (mod b)
    46. //然后拿上面的式子除以下面的式子即可推出(是同余运算,合理的)
    47. }
    48. }
    49. int qpow(ll a,int p)
    50. {
    51. int ans=1;
    52. for(;p;p>>=1,a=a*a%mod)if(p&1)ans=a*ans%mod;
    53. return ans;
    54. }
    55. int main()
    56. {
    57. //首先解题的理论基础是不妨设定二叉树上每条斜向左的边为胜,斜向右的为负,
    58. //在一颗完整二叉树上,任意 i条斜向左边+j条斜向右边 ,只要满足i+j==n都
    59. //能在二叉树上找到(指的是从跟到叶的路上的边),并且一种只能找到一条,那
    60. //么只能改变k次则无法改变那些路径上失败次数大于k的路,其他的路(失败边
    61. //<=k的)则sponsor可以任意选一条来改,那么我们把数字大的放到失败边多的
    62. //中,则最终算一下 ΣC_n^i,i>k 的数字有几个,这些就是接近n的,可以让
    63. //sponsor取不到的数字,那么剩下的最大就是被取走的了,因此题解就是这样
    64. //当然里面求解的时候还涉及了一些技巧,所以妙不可言!(ps:我学别人的
    65. ios_base::sync_with_stdio(0),cin.tie(0);
    66. cin>>n>>k;
    67. if(k>=n)
    68. {
    69. cout<<qpow(2,n);
    70. return 0;
    71. }
    72. init();
    73. //接下来就是要组合数了
    74. ll tmp=0;
    75. for(int i=k+1;i<=n;i++)//如n=3,k=2
    76. {
    77. tmp=(tmp+(ll)fac[n]*fac_inv[i]%mod*fac_inv[n-i]%mod)%mod;
    78. }
    79. cout<<(qpow(2,n)-tmp+mod)%mod;
    80. return 0;
    81. }

     

  • 相关阅读:
    logback日志文件sm3摘要运算
    计算机专业毕业论文java毕业设计网站SSM学生信息管理系统[包运行成功]
    LVS原理——详细介绍
    【Nacos配置中心】对配置文件内容进行加密
    3D全景:为各行业提供更真实的交互体验
    人工智能领域:面试常见问题超全(深度学习基础、卷积模型、对抗神经网络、预训练模型、计算机视觉、自然语言处理、推荐系统、模型压缩、强化学习、元学习)
    广读论文核心思路汇总笔记 (一些有意思的论文and论文在研究的一些有意思的问题or场景应用)
    [学习记录] SpringBoot 2. 底层注解
    阿里云一键登录(号码认证服务)
    科学计算与仿真-高斯牛顿法的非线性最小二乘问题简单介绍与应用
  • 原文地址:https://blog.csdn.net/PONY_10001/article/details/126678997