Problem

Description

你有一个 \(N\) 行、\(M\) 列的、每个格子都填写着 0 的表格。你进行了下面的操作:

  • 对于每一行 \(i\) ,选定自然数 \(r_i\) (\(0\leq r_i\leq M\)),将这一行最左边的 \(r_i\) 个格子中的数 \(+1\).
  • 对于每一列 \(i\) ,选定自然数 \(c_i\) (\(0\leq c_i\leq N\)),将这一列最上边的 \(c_i\) 个格子中的数 \(+1\).

这样,根据你选定的 \(r_1,r_2,\ldots,r_N,c_1,c_2,\ldots,c_M\) ,你就得到了一个每个格子要么是 0,要么是 1,要么是 2 的一个最终的表格。问本质不同的最终表格有多少种。两个表格本质不同当且进当它们有一个对应格子中的数不同。

Range

\(1\leq N,M \leq 5\cdot 10^5\)

Algorithm

容斥原理

Mentality

我们应该直接考虑重复的情况是怎么样的。

对于一对行和列,我们先假设其他行列的操作已经完成了,只需要考虑当前行列有多少种操作令结果不同。

然后缜密思索,我们发现只会有两个操作的结果是相同的。

假设我们正在考虑行 \(i\) 与列 \(j\) ,那么不难发现,只有当 \(r_i=j,c_j=i-1\) 和 \(r_i=j-1,c_i=i\) 这两种情况时,它们的结果会相同,对于其他任意情况而言,结果唯一。

则我们只需要枚举有几对行列选择了这两种会重复的状态的前一种,剩下的随便填,然后利用容斥原理计算答案即可。

对于枚举 \(k\) ,则有:

\[f(k)=C^N_k*C^M_k*k!*(M+1)^{N-k}*(N+1)^{M-k}
\]

则:

\[ans=\sum_{k=0}^{min(N,M)}(-1)^kf(k)
\]

Code

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
long long read() {
long long x = 0, w = 1;
char ch = getchar();
while (!isdigit(ch)) w = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit(ch)) {
x = (x << 3) + (x << 1) + ch - '0';
ch = getchar();
}
return x * w;
}
const int Max_n = 5e5 + 5, mod = 998244353;
int n, m, ans;
int fac[Max_n], ifac[Max_n];
int f[Max_n];
int ksm(int a, int b) {
int res = 1;
for (; b; b >>= 1, a = 1ll * a * a % mod)
if (b & 1) res = 1ll * res * a % mod;
return res;
}
int C(int n, int m) { return 1ll * fac[n] * ifac[m] % mod * ifac[n - m] % mod; }
int main() {
#ifndef ONLINE_JUDGE
freopen("F.in", "r", stdin);
freopen("F.out", "w", stdout);
#endif
n = read(), m = read();
if (n > m) swap(n, m);
fac[0] = ifac[0] = 1;
for (int i = 1; i <= m; i++) fac[i] = 1ll * fac[i - 1] * i % mod;
ifac[m] = ksm(fac[m], mod - 2);
for (int i = m - 1; i; i--) ifac[i] = 1ll * ifac[i + 1] * (i + 1) % mod;
for (int i = 0; i <= n; i++) {
f[i] = 1ll * C(n, i) * C(m, i) % mod * fac[i] % mod;
f[i] = 1ll * f[i] * ksm(m + 1, n - i) % mod * ksm(n + 1, m - i) % mod;
}
for (int i = 0; i <= n; i++)
ans = ((ans + ksm(-1, i & 1) * f[i]) % mod + mod) % mod;
cout << ans;
}

【AGC035F】Two Histograms的更多相关文章

  1. 论文阅读(Xiang Bai——【TIP2014】A Unified Framework for Multi-Oriented Text Detection and Recognition)

    Xiang Bai--[TIP2014]A Unified Framework for Multi-Oriented Text Detection and Recognition 目录 作者和相关链接 ...

  2. 【转】DBMS_STATS.GATHER_TABLE_STATS详解

    转自http://blog.itpub.net/26892340/viewspace-721935/ [作用] DBMS_STATS.GATHER_TABLE_STATS统计表,列,索引的统计信息(默 ...

  3. 【转】DPM--对象检测开山之作

    本文非原创,原文转载自:http://blog.csdn.net/ttransposition/article/details/12966521 DPM(Deformable Parts Model) ...

  4. 【转】DBMS_STATS.GATHER_TABLE_STATS详解 2012-04-22 09:20:10

    [转]DBMS_STATS.GATHER_TABLE_STATS详解 2012-04-22 09:20:10 分类: Linux 由于Oracle的优化器是CBO,所以对象的统计数据对执行计划的生成至 ...

  5. 【计算机视觉】Selective Search for Object Recognition论文阅读3

    Selective Search for Object Recoginition surgewong@gmail.com http://blog.csdn.net/surgewong       在前 ...

  6. 【概率论】3-7:多变量分布(Multivariate Distributions Part II)

    title: [概率论]3-7:多变量分布(Multivariate Distributions Part II) categories: Mathematic Probability keyword ...

  7. 【1】蛋白鉴定软件之X!Tandem

    目录 1. 简介 2.下载安装 3. 软件试用 4. 结果 5. FAQ 1. 简介 X!Tandem是GPM:The Global Proteome Machine(主要基于Web的开源用户界面,用 ...

  8. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  9. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

随机推荐

  1. 五分钟学会conda常用命令

    文章目录 conda常用命令 1. 获取版本号 2. 获取帮助 3. 环境管理 4. 分享环境 5. 包管理 conda常用命令 1. 获取版本号 conda --version 或 conda -V ...

  2. ASP.NET CORE 使用Consul实现服务治理与健康检查(2)——源码篇

    题外话 笔者有个习惯,就是在接触新的东西时,一定要先搞清楚新事物的基本概念和背景,对之有个相对全面的了解之后再开始进入实际的编码,这样做最主要的原因是尽量避免由于对新事物的认知误区导致更大的缺陷,Bu ...

  3. iOS---OBJC_ASSOCIATION_ASSIGN可能引起的Crash

    //OBJC_ASSOCIATION_ASSIGN类似于我们常用的assign,assign策略的特点就是在对象释放以后,不会主动将应用的对象置为nil,这样会有访问僵尸对象导致应用崩溃的风险.为了解 ...

  4. java 获取当前年份 月份,当月第一天和最后一天

    获取当前年份 月份,当月第一天和最后一天,工作中会经常用到,下面是代码: package basic.day01; import java.text.SimpleDateFormat; import ...

  5. 【机器学习实战】计算两个矩阵的成对距离(pair-wise distances)

    矩阵中每一行是一个样本,计算两个矩阵样本之间的距离,即成对距离(pair-wise distances),可以采用 sklearn 或 scipy 中的函数,方便计算. sklearn: sklear ...

  6. Cocos Creator 资源加载流程剖析【五】——从编辑器到运行时

    我们在编辑器中看到的资源,在构建之后会进行一些转化,本章将揭开Creator对资源进行的处理. 资源处理的整体规则 首先我们将Creator的开发和运行划分为以下几个场景: 编辑器 当我们将资源放到编 ...

  7. Redisson基本用法

    1.  Redisson Redisson是Redis官方推荐的Java版的Redis客户端.它提供的功能非常多,也非常强大,此处我们只用它的分布式锁功能. https://github.com/re ...

  8. .net core 获取树莓派的机器码,唯一ID,唯一串号

    今天在实际开发树莓派程序的时候,碰到了一个问题,需要获取到树莓派的唯一串号信息.必须在.net core的环境下: 那么如何实现呢?我们先查找树莓派的基本信息是储存在哪里的? 我们在下面的路径里找到了 ...

  9. python yield关键词使用总结

    python yield关键词使用总结 by:授客 QQ:1033553122 测试环境 win10 python 3.5 yield功能简介 简单来说,yield 的作用就是把一个函数变成一个 ge ...

  10. 2019QM大作业2-weyl半金属Landau Level

    目录 说明 for cnblog QM大作业2--weyl半金属的Landau Level \(\boldsymbol{Abstract}\) 说明 Landau Level 自旋与pauli mat ...