第八届山东acm省赛 C题 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.
Example Input

1 2 0
2 2
2 2 2
0 3
1 2
Example Output

2
3

组合数学+杨辉三角(upc 上一直T …)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<algorithm>

#define ll long long
#define inf 0x3f3f3f3f
#define maxn 100007  

const int mod = 1e9+7;
using namespace std;
ll f[maxn];
ll v[maxn];

ll quick_pow(int a,int n)
{
    long long  tmp = a%mod;
    long long  ans = 1;
    while(n)
    {
        if(n%2) 
            {
                ans*= tmp;
                ans %= mod;
            }
        tmp *= tmp;
        tmp %= mod;
        n/=2;
    }
    return ans;
}
void init()
{
    f[0]=1;
    for(int i=1;i<maxn;i++)
        f[i] = (long long )(f[i-1] * i) % mod; 
    for(int i=maxn-1;i>=0;i--)
        v[i] = quick_pow(f[i],mod-2) % mod;
}

ll C(int n,int m)
{
    if(n==m || m == 0) return 1;
    return ( (long long) (f[n] * v[m]) % mod * v[n-m] %mod );
//  return ( (long long ) ( f[n] * quick_pow(f[m],mod-2) % mod) * quick_pow(f[n-m],mod-2)%mod ) % mod;
}

int main()
{
    int n,t,w;
    long long ans;
    init();
    while(~scanf("%d%d%d",&n,&t,&w))
    {
        int x,c;
        int xx; 
        ans = 0;
        for(int i=0;i<n;i++)
            {
                scanf("%d%d",&x,&c);
                xx = abs(w - x);
                if(xx%2 && t%2 && t >= xx)
                    ans += C(t,(t+1)/2 + xx/2) *c% mod;
                else if(xx%2==0 && t%2==0 && t >= xx)
                    ans += C(t,xx/2+t/2)*c % mod;
                ans %= mod;
            }

        printf("%lld\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值