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;
}