山东省赛 C Firework (杨辉三角组合数逆元)

来源:互联网 发布:广西广电网络高清机顶盒 编辑:程序博客网 时间:2024/05/22 07:09

fireworks
Time Limit: 1000MS Memory Limit: 65536KB
Submit Statistic
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
Hint

Author

给你n个火的位置和目标位置,每一s有火的地方会往两边跑。。让你求t时间后,目标位置火的能量。
分析:画出来是一个杨辉三角变形。
当初脑子秀逗了
由于层数太多,所以就是求组合数和求逆元。
队友写的 一种是队友写的费马小定理求逆元

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const ll mod=1e9+7;ll inv[101010];ll fac[101010];const int maxn=1e5;void init(){    fac[0]=1;    for(int i=1;i<=maxn;i++)    {        fac[i]=fac[i-1]*i;        fac[i]%=mod;    }}ll quickM(ll a, ll b){    ll base = a%mod, ans = 1;    while(b){        if(b&1) ans = ans*base%mod;        base = base*base%mod;        b >>= 1;     }    return ans;}ll C(int n, int m){    return (fac[n]*quickM(fac[m], mod-2)%mod*quickM(fac[n-m],mod-2)%mod)%mod;}int main(){    int n,t,w,d,p;    init();    while(scanf("%d%d%d",&n,&t,&w)!=EOF)    {        memset(inv,0,sizeof inv);        for(int i=t,k=t;i>=0;i-=2,--k)        {            inv[i]=C(t,k);        }        ll ans=0;        for(int i=1;i<=n;i++)        {            scanf("%d%d",&d,&p);            ans+=p*inv[(int)abs(w-d)];            ans%=mod;        }        printf("%lld\n",ans );    }}/***************************************************User name: xiaoxiaobaiResult: AcceptedTake time: 424msTake Memory: 1800KBSubmit time: 2017-05-09 16:04:48****************************************************/

非lucas

#include <iostream>#include <cstdio>#include <cmath>#define LL long longusing namespace std;const LL mod = 1e9+7;const int maxn = 1e5;LL fact[maxn+5];LL inv[maxn+10];LL quickM(LL a, LL b){    LL base = a%mod, ans = 1;    while(b){        if(b&1) ans = ans*base%mod;        base = base*base%mod;        b >>= 1;     }    return ans;}void init(){    fact[0] = 1;    for(int i = 1; i <= maxn; ++i)    fact[i] = fact[i-1]*i%mod;    inv[maxn]=quickM(fact[maxn],mod-2);    for(int i=maxn-1;i>=0;i--)    {        inv[i]=inv[i+1]*(i+1);        inv[i]%=mod;    }}LL C(int n, int m){    return ((fact[n]*inv[m])%mod*(inv[n-m]))%mod;}inline int read(){    int x=0; bool f=0; char ch=getchar();    while (ch<'0' || '9'<ch) f|=ch=='-', ch=getchar();    while ('0'<=ch && ch<='9') x=x*10+ch-'0', ch=getchar();    return f?-x:x;}int main(){    int n, t, w, d, p, k; LL ans;    init();    while(~scanf("%d %d %d", &n, &t, &w)){        ans = 0;        for(int i = 1; i <= n; ++i){            d=read(),p=read();            k = abs(w-d);            if(k%2 && t%2 && k <= t){                ans += p*C(t, (t+1)/2+k/2);            }            if(k%2==0 && t%2==0 && k <= t){                ans += p*C(t, t/2+k/2);            }            ans %= mod;        }        printf("%lld\n", ans);    }    return 0;}

另一种是lucas 学校里的大佬写的 贼快

#include <iostream>#include <cstdio>#include <cmath>#define LL long longusing namespace std;const LL mod = 1e9+7;const int maxn = 1e5;LL fact[maxn+5];LL a[maxn+10];LL inv[maxn+10];void init(){    a[0] = a[1] = 1;    fact[0] = fact[1] = 1;    inv[1] = 1;    for(int i = 2; i <= 100005; i++)    {        fact[i] = fact[i-1] * i % mod;        inv[i] = (mod - mod/i)*inv[mod%i]%mod;        a[i] = a[i-1] * inv[i] % mod;    }}LL C(int n, int m){    return fact[n]*a[n-m]%mod*a[m]%mod;}inline int read(){    int x=0; bool f=0; char ch=getchar();    while (ch<'0' || '9'<ch) f|=ch=='-', ch=getchar();    while ('0'<=ch && ch<='9') x=x*10+ch-'0', ch=getchar();    return f?-x:x;}int main(){    int n, t, w, d, p, k; LL ans;    init();    while(~scanf("%d %d %d", &n, &t, &w)){        ans = 0;        for(int i = 1; i <= n; ++i){            d=read(),p=read();            k = abs(w-d);            if(k%2 && t%2 && k <= t){                ans += p*C(t, (t+1)/2+k/2);            }            if(k%2==0 && t%2==0 && k <= t){                ans += p*C(t, t/2+k/2);            }            ans %= mod;        }        printf("%lld\n", ans);    }    return 0;}/***************************************************User name: xiaoxiaobaiResult: AcceptedTake time: 176msTake Memory: 2560KBSubmit time: 2017-05-10 16:56:27****************************************************/
0 0