haut oj 1299 fireworks(杨辉三角规律)

来源:互联网 发布:高光谱遥感数据 编辑:程序博客网 时间:2024/05/16 09:50

题目链接

1299: fireworks
时间限制: 1 秒 内存限制: 64 MB
提交: 42 解决: 16
提交 状态
题目描述

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 contains multiple test cases.
For each test case:

The first line contains 3 integers n,T,w(n,T,|w|≤105)
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|≤105).
输出

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

样例输入

1 2 0
2 2
2 2 2
0 3
1 2
样例输出

2
3
提示

题意,有n个火苗,每个火苗每秒会分成两个,在左右相邻的位置各一个,自己这个位置的火苗消失,问你在T秒过后,在W这个位置会有多少个火苗

思路: 把火苗的分裂图如果画下来,就会发现他是一个杨辉三角,不过对于中间有些位置的0可以进行特判。
这里写图片描述

第一行为0秒时,第二行为1秒时,所以第T秒后,应该在(T+1)行,然后得到w与x的距离就知道它是第几个元素,最左边的从0开始,可直凡是在奇数位的都为0,偶数位置除以2,就能转化为杨辉三角的图形了。注意组合树的取模,这里是先求阶乘把它存到数组里

完整代码如下:

#include<iostream>#include<cstring>#include<set>#include<vector>#include<algorithm>#include<map>using namespace std;typedef long long ll;const int MAX = 100010;const ll MOD = 1000000007;ll N,T,W;ll Quick_pow(ll x,ll n){    ll res = 1;    while(n){        if(n & 1)   res = res*x % MOD;        x = x*x % MOD;        n >>= 1;    }    return res;}ll f[MAX];void init(){//预处理阶乘    f[0] = 1;    for(int i=1;i<=100000;++i){        f[i] = f[i-1]*i % MOD;    }}ll Get(ll n,ll m){//组合数    ll res;    res = f[n]*Quick_pow(f[m],MOD-2)%MOD * Quick_pow(f[n-m],MOD-2) % MOD;    return res;}int main(void){    init();    while(scanf("%lld%lld%lld",&N,&T,&W) != EOF){        ll res = 0,x,y;        for(int i=1;i<=N;i++){            scanf("%lld %lld",&x,&y);            ll dis = abs(W-x);            if(dis > T) continue;            ll m = T - dis;            if(m % 2 == 1)  continue;            m /= 2;            res = (res + y*Get(T,m)) % MOD;        }        printf("%lld\n",res);    }    return 0;}
原创粉丝点击