题目链接

题意

有一个 \(N × M\) 的二维平面, 平面上有 k 对虫洞, \(N, M ≤ 1e5, k ≤ 1e3\). 每对虫洞具有坐标 \(x_1, y_1, x_2, y_2\), 满足 \(x_1 ≤ x_2, y_1 ≤ y_2\), 当质点运动到 \((x_1, y_1)\) 时, 会被强制传送到 \((x_2, y_2)\). 问只向右和向上运动的情况下, 从点 (1, 1) 出发至点 (N, M) 有多少种走法, 对 1'000'000'007 取模.

题解

对所有虫洞按 \(x_1, y_1\) 为第一, 第二关键字排序. dp[i] 为从点 (1, 1) 运动至第 i 个虫洞有多少种走法. 不考虑其他虫洞时 \(dp[i] = C_{x_1-1+y_1-1}^{x_1-1}\), 当点 p 左下方有虫洞的起点 b 时, 路径 s-b-p 是不存在的, 减去之; 当点 p 左下方有虫洞的终点 e 时, 路径 s-b-e-p 是新的合法路径, 增加之. 这些数值都是直接用 \(dp[j] * C_{x_1-x_2+y_1-y_2}^{x_1-x_2}\) 算出来.

上述做法是来源于这一篇题解, 我基本是看了这篇才会做这题的. 但是有一点没有想明白, 如果一个虫洞的左下方有多个虫洞时, 它们之间应该是会互相干扰的, 为什么还可以这样直接套组合数算呢.

我的想法是这样的, 对于左下角的若干个虫洞, 不妨想象它们是按排序后的顺序依次出现, 这样也不影响它们的答案. 出现第一个虫洞时, 路径 s-b-p 确确实实是不存在, 需要减去的, 路径 s-b-e-p 也是新的合法路径, 需要加上; 现在出现了第二个虫洞, 路径 s-b-p 不受影响, 该不存在还是不存在; 而路径 s-b-e-p 发生变化, 可能在中途走到了第二个虫洞的起点, 而我们注意到下一项的意义中是包含了这个变化, 因为此时 dp[1](从 0 计数) 是已经受第 0 个虫洞影响下从点 (1, 1) 到该点的方案数. 后面再出现虫洞也一样可以这么理解(大概).

再回想一下为什么先要对虫洞排序再 dp, 因为要保证所有在某一虫洞左下方的虫洞答案都已经更新过.

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inc(i, l, r) for (int i = l; i <= r; i++)
#define dec(i, l, r) for (int i = l; i >= r; i--)
#define pii pair<int, int>
#define fi first
#define se second
#define pb push_back const int maxn = 1e3 + 5;
const int maxnum = 2e5;
const int mod = 1e9 + 7; int add(int a, int b) { return (a + b) % mod; }
int sub(int a, int b) { return (a - b + mod) % mod; }
int mul(int a, int b) { return 1LL * a * b % mod; } struct worm {
int x1, y1, x2, y2;
bool operator<(const worm &o) const {
if (x1 != o.x1) return x1 < o.x1;
return y1 < o.y1;
}
} w[maxn]; int dp[maxn], n, m, k; inline ll ksm(ll _a, ll _n) {
ll _r = 1;
while (_n) {
if (_n & 1) _r = _r * _a % mod;
_a = _a * _a % mod;
_n >>= 1;
}
return _r;
} int fac[maxnum + 5];
int C(int _n, int _m) {
return mul(mul(fac[_n], ksm(fac[_n - _m], mod - 2)), ksm(fac[_m], mod - 2));
} int cal(int x1, int y1, int x2, int y2) {
if (x1 > x2 || y1 > y2) return 0;
return C(x2 - x1 + y2 - y1, x2 - x1);
} int main() {
fac[0] = 1;
inc(i, 1, maxnum) fac[i] = mul(fac[i - 1], i);
while (scanf("%d %d %d", &n, &m, &k) != EOF && n) {
inc(i, 0, k - 1)
scanf("%d %d %d %d", &w[i].x1, &w[i].y1, &w[i].x2, &w[i].y2); sort(w, w + k);
w[k] = {n, m, n, m};
for (int i = 0; i <= k; i++) {
dp[i] = cal(1, 1, w[i].x1, w[i].y1);
for (int j = 0; j < i; j++) {
dp[i] = sub(
dp[i], mul(dp[j], cal(w[j].x1, w[j].y1, w[i].x1, w[i].y1)));
dp[i] = add(
dp[i], mul(dp[j], cal(w[j].x2, w[j].y2, w[i].x1, w[i].y1)));
}
}
printf("%d\n", dp[k]);
}
}

AOJ 2214: Warp Hall(计数+dp)的更多相关文章

  1. HDU5800 To My Girlfriend 背包计数dp

    分析:首先定义状态dp[i][j][s1][s2]代表前i个物品中,选若干个物品,总价值为j 其中s1个物品时必选,s2物品必不选的方案数 那么转移的时候可以考虑,第i个物品是可选可可不选的 dp[i ...

  2. CodeForces 176B Word Cut (计数DP)

    Word Cut Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit St ...

  3. [DP之计数DP]

    其实说实在 我在写这篇博客的时候 才刚刚草了一道这样类型的题 之前几乎没有接触过 接触过也是平时比赛的 没有系统的做过 可以说0基础 我所理解的计数dp就是想办法去达到它要的目的 而且一定要非常劲非常 ...

  4. HDU4815/计数DP

    题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=4815] 简单说一下题意: 有n道题,每到题答对得分为a[ i ],假如A不输给B的最小概率是P,那么A ...

  5. HDU 6377 度度熊看球赛 (计数DP)

    度度熊看球赛 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  6. 计数dp

    计数dp 计数类的$dp$没做过几个,所以之前都放到"思维"标签下了,后来发现原来这属于一类问题啊...搬过来了. 管道取珠:https://www.lydsy.com/Judge ...

  7. [SDOI2010]地精部落[计数dp]

    题意 求有多少长度为 \(n\) 的排列满足 \(a_1< a_2> a_3 < a_4 \cdots\) 或者 $a_1> a_2 < a_3 > a_4\cdo ...

  8. 【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas

    [题目]BZOJ 2111 [题意]求有多少1~n的排列,满足\(A_i>A_{\frac{i}{2}}\),输出对p取模的结果.\(n \leq 10^6,p \leq 10^9\),p是素数 ...

  9. 【AtCoder】AGC022 F - Leftmost Ball 计数DP

    [题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...

随机推荐

  1. Eureka停更了?试试Zookpper和Consul

    在Spring Cloud Netflix中使用Eureak作为注册中心,但是Eureka2.0停止更新,Eureka1.0 进入了维护状态.就像win7一样,同样可以用,但是官方对于新出现的问题并不 ...

  2. java.lang.reflect.UndeclaredThrowableException: null Caused by: org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for

    java.lang.reflect.UndeclaredThrowableException: null    at org.springframework.util.ReflectionUtils. ...

  3. 前端BOM和DOM

      前端基础之BOM和DOM   前戏 到目前为止,我们已经学过了JavaScript的一些简单的语法.但是这些简单的语法,并没有和浏览器有任何交互. 也就是我们还不能制作一些我们经常看到的网页的一些 ...

  4. css 超过标签定义的宽度后显示----

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. php7连接mysql8

    最近因为剁手买了mac所以在mac上搭建lnmp环境. 刚好看到mysql从5.7跳到8,性能据说快上一倍,果断尝鲜! lnmp基本都弄好了,但是到用php连接Mysql这一步出了岔子. 出错原因: ...

  6. java第一次上机练习作业

    1.已知a,b均是整型变量,写出将a,b两个变量中的值互换的程序.(知识点:变量和 运算符综合应用) int a = 5, b = 10; int temp; temp = a; a = b; b = ...

  7. python的C扩展调用,使用原生的python-C-Api

    1.在文件第一行包含python调用扩展的头文件 #include <Python.h> 2.用原生C写好需要调用的函数 int add_one(int a){ ; } 3.用python ...

  8. 《仙剑奇侠传柔情版》Java的简单实现(二)

    基于<仙剑奇侠传柔情版>Java的简单实现(二) 2018-12-02 by Kris 需要上次的GameFrame.class中窗口框架承载:https://www.cnblogs.co ...

  9. Magento2-2.3.4 win10安装完magento无法加载静态资源导致无法进入后台登录页面

    后台面无法进入,截图如下

  10. MySQL笔记(7)-- 事务和实现

    一.背景 前面有说到InnoDB是事务型引擎,那什么是事务?事务的特性是什么?它所对应的隔离级别是哪些?是怎么实现的?下面来详细讨论下. 二.事务的理解 事务就是一组原子性的SQL查询,或者说一个独立 ...