• [数论][组合数学]fireworks


    Problem Description

    Hmz likes to play fireworks, especially when they are put regularly.
    Now he puts some fireworks in a line. This time he put a trigger on each firework. With that trigger, each firework will explode and split into two parts per second, which means if a firework is currently in position x, then in next second one part will be in position x−1 and one in x+1. They can continue spliting without limits, as Hmz likes.
    Now there are n fireworks on the number axis. Hmz wants to know after T seconds, how many fireworks are there in position w?

    Input

    Input contains multiple test cases.
    For each test case:

    • The first line contains 3 integers n,T,w(n,T,|w|≤10^5)
    • In next n lines, each line contains two integers xi and ci, indicating there are ci fireworks in position xi at the beginning(ci,|xi|≤10^5).

    Output

    For each test case, you should output the answer MOD 1000000007.

    Sample Input

    1 2 0
    2 2
    2 2 2
    0 3
    1 2
    

    Sample Output

    2
    3

    思路:
    若0s时烟花在x=0处,则t=2,3,4...s时,各个位置处的烟花数量如图所示,发现它们构成一个杨辉三角。于是可以知道,t s时,在位置(0-t)+k*2(0<=k<=t)处的烟花数量为C(t,k),其他位置的烟花数量为0。所以给定烟花的初始位置x和经过的时间t,可以算出在位置w的烟花数量

    AC代码:
    #include <iostream>
    #include<cstdio>
    #define ll long long
    #define mod 1000000007
    using namespace std;
    
    ll f[100010];
    
    void init(){//预处理n!
      f[0]=1;
      for(ll i=1;i<=100005;i++){
        f[i]=i*f[i-1]%mod;
      }
    }
    
    ll qpow(ll x,ll n){
      ll ret=1;
      while(n){
         if(n&1) ret=(ret*x)%mod;
         x=(x*x)%mod;
         n>>=1;
      }
      return ret;
    }
    
    ll rev(ll x){
      return qpow(x,mod-2);
    }
    
    ll C(ll n,ll m){//利用逆元求组合数
      return f[n]%mod*rev(f[m])%mod*rev(f[n-m])%mod;
    }
    
    int main()
    {
        init();
        ll n,t,w;
        while(scanf("%lld%lld%lld",&n,&t,&w)!=EOF){
            ll ans=0;
            for(ll i=1;i<=n;i++){
                ll x,c;
                scanf("%lld%lld",&x,&c);
                ll stax=x-t;
                if((w-stax)%2!=0) continue;
                else{
                    ll k=(w-stax)/2;
                    if(k<0||k>t) continue;
                    else ans=(ans+(c*C(t,k))%mod)%mod;
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    转载请注明出处:https://www.cnblogs.com/lllxq/
  • 相关阅读:
    windows 2012 r2怎么进入本地组策略
    ESXI | ESXI6.7如何在网页端添加用户并且赋予不同的权限
    exsi 6.7u2 不能向winows虚拟机发送ctrl+alt+del
    正确安装Windows server 2012 r2的方法
    gitkraken生成ssh keys并连接git
    GitKraken 快速配置 SSH Key
    寒假学习进度六
    寒假学习进度五——活动之间的跳转以及数据的传递
    寒假学习进度四(解决Android studio的com.android.support.v4.view.ViewPager报错问题)
    寒假学习进度三——安卓的一些基本组件
  • 原文地址:https://www.cnblogs.com/lllxq/p/8901669.html
Copyright © 2020-2023  润新知