ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

8.6

2022-08-07 21:30:09  阅读:132  来源: 互联网

标签:begin end dbinom 8.6 int leq Bmatrix


CF1716F

题意:

有\(n\)个不同的包,每个包里有编号为\(1\sim m\)的球恰好一个。

从每个包里取一个球出来,假设某个取球方案中,奇数编号的球恰好有\(x\)个,则该方案的贡献是\(x^k\)。

求所有取球方案的贡献和。模\(998244353\)

\(1\leq T\leq 5000\)

\(1\leq n,m\leq 998244352,1\leq k\leq 2000\)

题解:

算贡献

设奇数编号球有\(i\)个,\(x=\lceil\frac{m}{2}\rceil,y=m-x\),\(x\)是奇数编号的球的总数,\(y\)是偶数编号的球的总数

\[ans=\sum_{i=1}^ni^k\dbinom{n}{i}x^iy^{n-i} \]

现在考虑把关于\(i\)的求和变成关于\(k\)的求和

套用第二类斯特林数转化法

\[i^k=\sum_{j=0}^i\ \begin{Bmatrix}k \\ j\end{Bmatrix}*j!*\dbinom{i}{j} \]

解释:组合意义来看,第二类斯特林数\(\begin{Bmatrix}n \\ m\end{Bmatrix}\)是\(n\)个有编号的球放入\(m\)个无标号的盒子,没有空盒子的方案数。

那么\(i^k\)的组合意义是把\(k\)个有编号的球放入\(i\)个有编号的盒子,有空盒子的方案数。(每个球都有\(i\)种选择方案)

根据这个意义,我们枚举有多少个盒子非空,即\(j=0->k\)

然后从\(i\)个盒子中选出\(j\)个,并且标号,即\(j!*\dbinom{i}{j}\)

最后再把这些球放进去\(\begin{Bmatrix}k \\ j\end{Bmatrix}\)

为什么是\(j!\)不是\(k!\),因为空盒是不用标号的,空盒里面的内容都一样,非空盒哪怕里面球的数量一样,球的编号也不一样。

关于第二类斯特林数的递推:

\[\begin{Bmatrix}n \\ m\end{Bmatrix}=\begin{Bmatrix}n-1 \\ m-1\end{Bmatrix}+m\begin{Bmatrix}n-1 \\ m\end{Bmatrix} \]

解释:考虑最后一个球放在哪,要么自己新开一个盒子,要么放在原有的\(m\)个盒子其中的一个。

把转化后的式子代回去

\[ans=\sum_{i=1}^n\sum_{j=0}^i\ \begin{Bmatrix}k \\ j\end{Bmatrix}*j!*\dbinom{i}{j}*\dbinom{n}{i}*x^i*y^{n-i}\\ =\sum_{i=1}^n\sum_{j=0}^i\ \begin{Bmatrix}k \\ j\end{Bmatrix}*j!*\dbinom{n-j}{i-j}*\dbinom{n}{j}*x^i*y^{n-i}\\ \]

解释下这里的变换:

\(\dbinom{i}{j}*\dbinom{n}{i}\)可以理解为,先从\(n\)个里面选\(i\)个二等奖,再从\(i\)个里面选\(j\)个一等奖

\(\dbinom{n-j}{i-j}*\dbinom{n}{j}\)可以变化为,直接从\(n\)个里面选\(j\)个一等奖,再从剩下的人里面选\(i-j\)个二等奖

\[ans=\sum_{j=0}^k\begin{Bmatrix}k \\ j\end{Bmatrix}*j!*\dbinom{n}{j}\sum_{i=j}^n\dbinom{n-j}{i-j}x^iy^{n-i} \]

切换下标,设\(i'=i-j,i=i'+j\)

\[ans=\sum_{j=0}^k\begin{Bmatrix}k \\ j\end{Bmatrix}*j!*\dbinom{n}{j}\sum_{i'=0}^{n-j}\dbinom{n-j}{i'}x^{i'+j}y^{n-j-i'}\\ =\sum_{j=0}^k\begin{Bmatrix}k \\ j\end{Bmatrix}*j!*\dbinom{n}{j}*(x+y)^{n-j}*x^j \]

就做完了,那个组合数虽然\(n\)很大,但是可以递推。

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define double long double
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-15)
    const int N=3e5+10,mod=998244353,inv2=5e8+4,inf=2e9;
    vector S2(2001,vector<int>(2001));
    vector<int> fac(2001);
    void _init_(int n=2000)
    {
        S2[0][0]=1;
        for(int i=0;i<=n;++i)
        {
            for(int j=1;j<=i;++j)
            {
                S2[i][j]=(S2[i-1][j-1]+j*S2[i-1][j])%mod;
            }
        }
        fac[0]=1;
        for(int i=1;i<=n;++i) fac[i]=fac[i-1]*i%mod;
    }
    inline void main()
    {
        int n,m,k;cin>>n>>m>>k;
        int ans=0;
        auto fast=[&](int x,int k) -> int
        {
            int ret=1;
            while(k)
            {
                if(k&1) ret=ret*x%mod;
                x=x*x%mod;
                k>>=1;
            }
            return ret;
        };
        int x=(m+1)/2,y=m-x,cc=1;
        int lim=min(n,k);
        for(int i=0;i<=lim;++i)
        {
            ans=(ans+S2[k][i]*fac[i]%mod*cc%mod*fast(x+y,n-i)%mod*fast(x,i)%mod)%mod;
            //cout<<n<<' '<<i<<' '<<cc<<"!!!"<<endl;
            cc=cc*(n-i)%mod*fast(i+1,mod-2)%mod;
            
        }
        cout<<ans<<'\n';
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    red::_init_();
    int qwq=1; cin>>qwq;
    while(qwq--) red::main();
    return 0;
}
/*

*/

CF1083E

题意:

给定 \(n\) 个平面直角坐标系中左下角为坐标原点,右上角为 \((x_i, y_i)\) 的矩形,每一个矩形拥有权值 \(a_i\),且保证任意两个矩形的面积不会出现包含关系。你的任务是选出若干个矩形,使得选出的矩形的面积并减去矩形的权值之和尽可能大。输出最大值。

\(1 \leq n \leq 10^6, 1 \leq x_i, y_i \leq 10^9, 0 \leq a_i \leq x_i \cdot y_i\),给出的矩形保证任意两个矩形的面积不会出现包含关系。

题解:

把矩形按右上角的\(x\)坐标排序,然后直接列方程

\[dp[i]=dp[j]+(x_i-x_j)*y_i-a_i\\ dp[j]=y_i*x_j+dp[i]-x_iy_i+a_i\\ y(j)=dp[j],x(j)=y_j,k=y_i \]

就可以斜率优化了,因为斜率\(k_i\)是递减的,所以维护一个左上突壳

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define double long double
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define lowbit(i) ((i)&(-i))
#define mid ((l+r)>>1)
#define eps (1e-15)
    const int N=3e5+10,mod=998244353,inv2=5e8+4,inf=2e9;
    void _init_(int n=2000) {}
    struct node {double x,y,z;};
    inline void main()
    {
        int n;
        cin>>n;
        vector<node> a(n+1);
        for(int i=1;i<=n;++i)
        {
             int x,y,z;cin>>x>>y>>z;
             a[i].x=x,a[i].y=y,a[i].z=z;
            //cin>>a[i].x>>a[i].y>>a[i].z;
        }
        sort(a.begin()+1,a.end(),[](node &i,node &j){return i.x<j.x;});
        vector<int> dp(n+2),q(n+2);
        int head=0,tail=0;
        auto y=[&](int &i) -> double{return dp[i];};
        auto x=[&](int &i) -> double{return a[i].x;};
        auto slope=[&](int &i,int &j) -> double
        {
            return 1.0*(y(i)-y(j))/(x(i)-x(j));
        };
        int ans=0;
        for(int i=1;i<=n;++i)
        {
            while(head<tail&&slope(q[head],q[head+1])>=1.0*a[i].y) ++head;
            int j=q[head];
            dp[i]=dp[j]+(a[i].x-a[j].x)*a[i].y-a[i].z;
            ans=max(ans,dp[i]);
            while(head<tail&&slope(q[tail],q[tail-1])<=slope(q[tail-1],i)) --tail;
            q[++tail]=i;
        }
        cout<<ans<<'\n';
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    red::_init_();
    int qwq=1; //cin>>qwq;
    while(qwq--) red::main();
    return 0;
}
/*

*/

标签:begin,end,dbinom,8.6,int,leq,Bmatrix
来源: https://www.cnblogs.com/knife-rose/p/16559939.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有