【学习笔记】[AGC021F] Trinity

这篇具有很好参考价值的文章主要介绍了【学习笔记】[AGC021F] Trinity。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第一步有点难😅

考虑加入每一列,发现我们只关心当前还未确定的行的数目

d p i , j dp_{i,j} dpi,j表示有 i i i列,其中 j j j行未确定的方案数。钦定每一列至少有一个黑色格子。

d p i , j = j ( j + 1 ) 2 d p i − 1 , j + ∑ k ≥ 1 ∑ k ≤ l ≤ j ( j − l + 1 ) ( l k ) d p i − 1 , j − k dp_{i,j}=\frac{j(j+1)}{2}dp_{i-1,j}+\sum_{k\ge 1}\sum_{k\le l\le j}(j-l+1)\binom{l}{k}dp_{i-1,j-k} dpi,j=2j(j+1)dpi1,j+k1klj(jl+1)(kl)dpi1,jk

暴力 D P DP DP的复杂度为 O ( N 3 M ) O(N^3M) O(N3M),考虑优化

发现可以看成从 j + 2 j+2 j+2个数中选 k + 2 k+2 k+2个数的方案数,上面的式子其实是在枚举倒数第二个被选中的数的位置。

d p i , j = j ( j + 1 ) 2 d p i − 1 , j + ∑ k < j ( j + 2 k ) d p i − 1 , k dp_{i,j}=\frac{j(j+1)}{2}dp_{i-1,j}+\sum_{k<j}\binom{j+2}{k}dp_{i-1,k} dpi,j=2j(j+1)dpi1,j+k<j(kj+2)dpi1,k

这样优化到了 O ( N 2 M ) O(N^2M) O(N2M)

将组合数拆成阶乘的形式,可以用多项式优化。

复杂度 O ( N M log ⁡ N ) O(NM\log N) O(NMlogN)文章来源地址https://www.toymoban.com/news/detail-654069.html

#include<bits/stdc++.h>
#define fi first
#define se second
#define ll long long
#define pb push_back
#define db double
#define inf 0x3f3f3f3f
using namespace std;
const int mod=998244353;
const int N=8005;
const int M=205;
int n,m;
ll dp[N],res;
ll fac[N],inv[N];
ll fpow(ll x,ll y=mod-2){
    ll z(1);
    for(;y;y>>=1){
        if(y&1)z=z*x%mod;
        x=x*x%mod;
    }return z;
}
void init(int n){
    fac[0]=1;for(int i=1;i<=n;i++)fac[i]=fac[i-1]*i%mod;
    inv[n]=fpow(fac[n]);for(int i=n;i>=1;i--)inv[i-1]=inv[i]*i%mod;
}
ll binom(int x,int y){
    if(x<0||y<0||x<y)return 0;
    return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
void add(ll &x,ll y){
    x=(x+y)%mod;
}
int len;
ll invlen;
ll omega[N<<2][2];
void ntt(vector<ll>&a,int len,int f=0){
    int k=0;while((1<<k)<len)k++;
    for(int i=0;i<len;i++){
        int t=0;
        for(int j=0;j<k;j++){
            if(i>>j&1)t+=(1<<k-j-1);
        }if(i<t)swap(a[i],a[t]);
    }
    for(int l=2;l<=len;l<<=1){
        int k=l/2;ll x=omega[l][f];
        for(int i=0;i!=len;i+=l){
            ll y=1;
            for(int j=0;j<k;j++){
                ll tmp=a[i+j+k]*y%mod;
                a[i+j+k]=(a[i+j]-tmp)%mod;
                a[i+j]=(a[i+j]+tmp)%mod;
                y=y*x%mod;
            }
        }
    }if(f)for(int i=0;i<len;i++)a[i]=a[i]*invlen%mod;
}
struct poly{
    vector<ll>a;
    friend poly operator *(poly a,poly b){
        ntt(a.a,len),ntt(b.a,len);
        for(int i=0;i<len;i++)a.a[i]=a.a[i]*b.a[i]%mod;
        ntt(a.a,len,1);
        return a;
    }
}f,g;
signed main(){
	ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n>>m,init(max(n,m)+2);
    dp[0]=1;
    len=1;while(len<=2*(n+2))len<<=1;invlen=fpow(len);
    omega[len][0]=fpow(3,(mod-1)/len);
    omega[len][1]=fpow(3,mod-1-(mod-1)/len);
    for(int i=len/2;i;i>>=1){
        omega[i][0]=omega[i<<1][0]*omega[i<<1][0]%mod;
        omega[i][1]=omega[i<<1][1]*omega[i<<1][1]%mod;
    }
    g.a.resize(len);for(int i=3;i<=n+2;i++)g.a[i]=inv[i];
    add(res,1);
    for(int i=1;i<=m;i++){
        f.a.clear(),f.a.resize(len);
        for(int j=0;j<=n;j++)f.a[j]=dp[j]*inv[j]%mod;
        f=f*g;
        for(int j=0;j<=n;j++){
            dp[j]=(j*(j+1)/2*dp[j]%mod+f.a[j+2]*fac[j+2])%mod;
        }for(int j=0;j<=n;j++)add(res,dp[j]*binom(n,j)%mod*binom(m,i));
    }
    cout<<(res+mod)%mod;
}

到了这里,关于【学习笔记】[AGC021F] Trinity的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (学习笔记-调度算法)进程调度算法

    进程调度算法也称 CPU 调度算法,毕竟进程是由 CPU 调度的。 当 CPU 空闲时,操作系统就选择内存中标的某个 [就绪状态] 的进程,将其分配给 CPU。 什么时候会发生CPU调度呢?通常有以下情况: 当进程从运行状态转换到等待状态 当进程从运行状态转换到就绪状态 当进程从等待

    2024年02月11日
    浏览(41)
  • 算法设计与分析学习笔记之二分查找算法

    二分查找只适用于有序的顺序表,非严格递增或是非严格递减都行。 二分查找运用到了分治的思想,将整体逐渐分为许多个小的部分,让整体的解变为诸多小部分解的合成,要求整体可以分解,小部分的解汇合之后可以得到整体部分的解。 至此,结束。 如果你觉得这篇文章

    2024年02月09日
    浏览(45)
  • 【嵌入式算法】学习笔记(一):数字滤波算法

    最近在做直流电机的毕设中,由于需要采集转速,电流,电压,温度等参数,常规的采集容易受到干扰,所以特意复习了一下关于数字滤波有关的知识,并作出相应的整理。 本文对数字滤波进行简单介绍,讲解七种常用的滤波算法并用C语言实现,并比较其优缺点 。由于篇幅

    2023年04月22日
    浏览(91)
  • Manacher算法学习笔记

    Manacher算法就是马拉车。 Manacher算法就是用于解决回文子串的个数的。 P3805:【模板】manacher 算法 给出一个只由小写英文字符 (texttt a,texttt b,texttt c,ldotstexttt y,texttt z) 组成的字符串 (S) ,求 (S) 中最长回文串的长度。 为了找到最长的回文串的长度,我们首先就要考虑如何

    2024年02月09日
    浏览(29)
  • 进阶搜索算法 学习笔记

    DATE 20231031:补充一道好题 P4872 OIer们的东方梦(Dijkstra 分层图最短路)。 双向广搜、双向深搜 堆优化的 Dijkstra 一颗小小的 A-STAR 不大聪明的 IDDFS(IDS) 可爱的 IDA-STAR 这是进阶搜索算法,不说了直接上例题: 以“P1514 引水问题”为例: 点击查看代码 算法思想 在搜索的时候

    2024年02月09日
    浏览(43)
  • 各种排序算法学习笔记

    Docs https://r0dhfl3ujy9.feishu.cn/docx/XFlEdnqv9oCEoVx7ok8cpc4knnf?from=from_copylink 如果你认为有错误,欢迎指出!

    2024年02月01日
    浏览(33)
  • 算法基础学习笔记——②二分

    ✨ 博主:命运之光 ✨ 专栏: 算法基础学习 前言: 算法学习笔记记录日常分享,需要的看哈O(∩_∩)O,感谢大家的支持! 1.有单调性一定可以二分,没有单调性也可能二分 2.二分的本质是边界,只要找到某种性质,使得整个区间一分为二, 那么就可以用二分把整个边界点二

    2024年02月09日
    浏览(73)
  • 算法基础学习笔记——①排序

    ✨ 博主:命运之光 ✨ 专栏: 算法基础学习 前言: 算法学习笔记记录日常分享,需要的看哈O(∩_∩)O,感谢大家的支持! 因为x参与交换之后仍然会被留在左右区间中的一个里。 1.确定分界点:(这里的分界点不一定是x,可以随意取值,常用取值方法如下) q[l],q[(l+r)/2],q[r],随机

    2024年02月07日
    浏览(46)
  • 算法学习笔记-exgcd

    (operatorname {exgcd}) ,顾名思义,是 (gcd) 的一种扩展。 (gcd) 是求最大公因数,所用到的是辗转相除法,基于 (gcd(a,b)=gcd(b,amod b) (ab)) 的原理,在学习 (operatorname{exgcd}) 前,请确保已掌握 (gcd) ,并懂得一点数学归纳法。如果您已掌握这些前置知识,请开始学习。 先看

    2024年02月13日
    浏览(28)
  • 全覆盖规划算法学习笔记-------

    通过对比提供的ROS全覆盖规划算法:确定Boustrophedon Planner和Grid-based Local Energy Minimization Planner具备过程应用价值,这里选择后者进行重点研究。 参考: 官网 ipa_room_exploration - ROS Wiki Indoor Coverage Path Planning: Survey, Implementation, Analysis 算法说明与翻译: 使用Bormann-Richard、Joshua Ha

    2024年01月24日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包