Fireworks(山东省第8届ACM省赛)逆元,组合数

来源:互联网 发布:鹊桥高佣金淘宝客软件 编辑:程序博客网 时间:2024/06/05 19:30

fireworks

Time Limit: 1000MS Memory Limit: 65536KB
Submit Statistic Discuss

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 02 22 2 20 31 2

Example Output

 3 

 2



这题的大概意思就是定义一种能无限炸裂的烟花,每秒钟烟花炸裂后原位置什么都不会剩下,而和他相邻的两个位置会出现两个子烟花,然后让你求t秒后位置w的烟花个数。题目又给定了n组烟花,所以要求的是n组烟花在位置w的子烟花个数。

 仔细观察会发现,烟花分裂的规律符合杨辉三角(去掉所有为0的点),求组合数,由于组合数太大,所以用逆元来代替除法取模。
本题使用快速幂跟费马小定理求逆元。
#include#includeusing namespace std;typedef long long ll;const int maxn = 1299709 + 10;const int maxt = 100200;const int inf = 0x3f3f3f3f;const ll INF = 0x7f7f7f7f7f7f7f7f;const int mod = 1e9 + 7;const double pi = acos(-1.0);const double eps = 1e-8;int a[maxn];ll C[maxn];ll quick_mod(ll x, int n){    ll ret = 1;    while(n){        if(n & 1) ret = ret * x % mod;        x = x * x %mod;        n >>= 1;    }    return ret;}void init(int t){    C[0] = 1;    for(int i = 1; i <= t; ++i){        C[i] = C[i - 1] * (t - i + 1) % mod * quick_mod(i, mod - 2) % mod;    }}ll solve(ll x, int w, int l){    int d = abs(x - w);    ll sum = 0;    if(l & 1){       if(d < l && d % 2 == 0)            sum += C[l / 2 - d / 2];    }    else{        if(d < l && d & 1)            sum += C[l / 2 + (d - 1) / 2];    }    return sum;}int main(){    int n, t, w;    while(scanf("%d%d%d", &n, &t, &w) == 3){        ll ans = 0;        init(t);        for(int i = 0; i < n; ++i){            int x, c;            scanf("%d%d", &x, &c);            ans += c * solve(x, w, t + 1);            ans %= mod;        }        printf("%lld\n", ans);    }}





阅读全文
0 0
原创粉丝点击