• [2020多校A层12.1] 礼物


    计算

    [sum_isum_{j e i}{a_i+b_i+a_j+b_jchoose{a_i+a_j}} ]

    (nle10^5,sum a_i+sum b_ile2 imes10^7)


    感觉思维非常僵化啊,当时一看就以为是BBQ hard的加强版,然后直接写了个复杂度有点爆炸的分治做法,小点做BBQ hard,大点暴力。

    然而这题并没有这么复杂,我们因为值域不是很大,所以考虑在值域上做点操作。

    考虑 (a_i+b_i+a_j+b_jchoose{a_i+a_j}) 这个式子的组合意义,其实是从 (a_i+b_i+a_j+b_j) 个物品里选 (a_i+a_j) 个,那么我们考虑分两次选这个物品,第一次从 (a_i+b_i) 里选 (t) 个,那么第二次就是从 (a_j+b_j) 里选 (a_i+a_j-t) 个,那么我们可以等价写成下面这个式子:

    [egin{aligned}=&sum_{t=0}^{a_i+a_j}{a_i+b_ichoose{t}} imes{a_j+b_jchoose a_i+a_j-t}\=&sum_{t=-a_i}^{a_j}{a_i+b_ichoose a_i+t} imes{a_j+b_jchoose a_j-t}end{aligned} ]

    (t) 如果很大左边的组合数就是 (0) ,那么 (t) 的上界变成 (b_i) ,如果 (b_i>a_j) ,那么右边的组合数就是 (0),所以不会多算。

    于是两边可以分别算和再求乘积,那么对于右边那一项可以开个桶记录和,这样就可以在 (O(sum a_i+sum b_i)) 的复杂度做完了。

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    const int N = 1e5;
    const int MAXN = 2e7;
    const int p = 1e9 + 7;
    using namespace std;
    struct thi
    {
        int a,b;
    }c[N + 5],d[N + 5];
    int n,a[N + 5],b[N + 5],ans,inv[MAXN + 1],fac[MAXN + 1],sm[MAXN * 2 + 5];
    int mypow(int a,int x){int s = 1;for (;x;x & 1 ? s = 1ll * s * a % p : 0,a = 1ll * a * a % p,x >>= 1);return s;}
    int C(int n,int m)
    {
        return 1ll * fac[n] * inv[m] % p * inv[n - m] % p;
    }
    int main()
    {
        //freopen("gift.in","r",stdin);
        //freopen("gift.out","w",stdout);
        scanf("%d",&n);
        for( int i = 1;i <= n;i++)
            scanf("%d%d",&a[i],&b[i]);
        fac[0] = 1;
        for (int i = 1;i <= MAXN;i++)
            fac[i] = 1ll * fac[i - 1] * i % p;
        inv[MAXN] = mypow(fac[MAXN],p - 2);
        for (int i = MAXN - 1;i >= 0;i--)
            inv[i] = 1ll * inv[i + 1] * (i + 1) % p;
        for (int i = 1;i <= n;i++)
        {
            for (int t = -a[i];t <= b[i];t++)
                ans += 1ll * C(a[i] + b[i],t + a[i]) * sm[-t + MAXN] % p,ans %= p;
            for (int t = -a[i];t <= b[i];t++)
                sm[t + MAXN] += C(a[i] + b[i],a[i] + t) % p,sm[t + MAXN] %= p;
        }
        cout<<(2ll * ans % p + p) % p<<endl;
        return 0;
    }
    
  • 相关阅读:
    03.《架构漫谈》阅读笔记
    02.《架构漫谈》阅读笔记
    03.《架构之美》阅读笔记
    02.《架构之美》阅读笔记
    01.《架构之美》阅读笔记
    软件架构中的质量属性--以淘宝网为例(小论文)
    MVC框架介绍分析
    论面向服务架构设计及其应用
    1.26学习进度总结
    1.24学习进度总结
  • 原文地址:https://www.cnblogs.com/sdlang/p/14068221.html
Copyright © 2020-2023  润新知