题解

我深思熟虑许久才算是明白个大概的计数问题吧

先是转化成一个矩形,列一条直线y = x,y = x - (m + 1)我们从(0,0)走到(n + m + 1,m + 1)就是答案

因为我们起始相当于第一行缺一个0,然后有m+1种转移的方案,每次在距左边界j的地方某个点向上走表示转移到缺j - 1,向右走一步走到了缺j,再走一步走到缺j + 1....

我们把向上走当做-1,向右走当做+1,我们可以建立一个新的模型

就是起点为\((0,0)\)终点为\((2 * n + m + 1,m + 1)\),每次可以走到\((x + 1,y + 1)\)或者走到\((x + 1,y - 1)\)

不能碰到\(y = -1\)或者\(y = m + 2\)

我们要用总方案去掉碰到\(y = -1\)和碰到\(y = m + 2\)再加上两个都碰到的

我们对于碰到\(y = -1\)我们就关于让终点关于\(y = -1\)对称,求原点到那里的方案数,因为每条不合法的路径对应一条到翻折点的路径在和\(y = -1\)第最后一个交点处后的路径沿\(y = -1\)翻折即可

我们把两个都碰到的拆成最后一个碰到的是\(y = -1\)记为A和第最后一个碰到的是\(y = m + 2\)记为B

举个例子

我们对于\(y = -1\)统计第最后碰到的是A

对于一条需要被加上的路径(也就是影响需要被抵消的路径)

经历的顺序记为

ABABA

那么我们

去掉了后缀为AB 和A 的

再加上后缀为AB 和 ABA的

再减去后缀为ABA 和 ABAB的

直到不能计算了为止

怎么计算后缀为AB 和 ABA的两种情况呢

我们把\(y = m + 2\)对着\(y = -1\)再次翻折,把(n * 2 + m + 1,m + 1)这个点对着\(y = -1\)翻折后,再次对着\(y = -m - 4\)翻折

计算(0,0)到目标点的答案就是我们想要的

最后我们只要把直线不断翻折直到不能达成为止

我们再对\(y = m + 1\)做相同的操作即可

这道题要是考场上给我,我也只能写60分暴力滚粗了……

代码

#include <bits/stdc++.h>
#define enter putchar('\n')
#define space putchar(' ')
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define eps 1e-8
#define MAXN 4000005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned long long u64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 - '0' + c;
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
const int MOD = 1000000007;
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
int fac[MAXN],invfac[MAXN],inv[MAXN],N,M,ans,x;
int C(int n,int m) {
if(n < m) return 0;
return mul(fac[n],mul(invfac[m],invfac[n - m]));
}
int F(int n,int m) {
return C(n,(n - m) / 2);
}
void Calc(int y,int y_1,int y_2) {
while(1) {
y = 2 * y_1 - y;
y_2 = 2 * y_1 - y_2;
if(abs(y) > x) break;
ans = inc(ans,MOD - F(x,y));
y = 2 * y_2 - y;
y_1 = 2 * y_2 - y_1;
if(abs(y) > x) break;
ans = inc(ans,F(x,y));
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
read(N);read(M);
inv[1] = 1;
for(int i = 2 ; i <= 4000000 ; ++i) inv[i] = mul(inv[MOD % i],MOD - MOD / i);
fac[0] = invfac[0] = 1;
for(int i = 1 ; i <= 4000000 ; ++i) {
fac[i] = mul(fac[i - 1],i);
invfac[i] = mul(invfac[i - 1],inv[i]);
}
x = 2 * N + M + 1;
ans = inc(ans,F(x,M + 1));
Calc(M + 1,-1,M + 2);Calc(M + 1,M + 2,-1);
out(ans);enter;
}

【LOJ】#2109. 「JLOI2015」骗我呢的更多相关文章

  1. 「JLOI2015」骗我呢 解题报告?

    「JLOI2015」骗我呢 这什么神仙题 \[\color{purple}{Link}\] 可以学到的东西 对越过直线的东西翻折进行容斥 之类的..吧? Code: #include <cstd ...

  2. @loj - 2106@ 「JLOI2015」有意义的字符串

    目录 @description@ @solution@ @accepted code@ @details@ @description@ B 君有两个好朋友,他们叫宁宁和冉冉.有一天,冉冉遇到了一个有趣 ...

  3. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  4. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  5. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  6. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  7. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  8. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

  9. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

随机推荐

  1. SSH & Git

    SSH基本用法 SSH服务详解 work with git branch some tips for git setup and git config git and github ssh servi ...

  2. 'sudo'不是内部或外部命令,,,,的解决办法

    [说明] Windows系统从 Vista 版本开始加入了 UAC 机制,这导致没有足够权限的程序无法获取到一些关键资源.在 Linux 下我们可以使用 sudo 命令方便地提升当前程序的执行权限,但 ...

  3. spring data jpa查询部分字段、多余附加字段

    spring data jpa查询部分字段 第一种方法:使用 model 查询时转化 首先建立一个 model ,写上自己想要查询的字段,然后写上构造函数,这步很重要,因为spring jpa 转化时 ...

  4. 【51nod1073】约瑟夫环1

    题目大意:给定 \(N\) 个人围成一个圈,每隔 \(M\) 个人杀一个,求最后活着的人的编号. 题解:环会涉及模运算,所以先将 \(1 \rightarrow N\) 映射为 \(0 \righta ...

  5. ES6学习(二)基础命令

    一.Let 和 const  作用域的概念:在es5之前是有两个作用域,一个是全局作用域,另外一个是函数作用域,在es6中就多了这样一个块作用域.在这里let 和 const 就是传说中的块作用域,它 ...

  6. shell常用编程格式

    WORKSPACE=$(cd $(dirname $0)/; pwd) cd $WORKSPACE   mkdir -p var   module=jmxmon version=0.0.2 app=& ...

  7. NodeJS API Process全局对象

    Process 全局对象,可以在代码中的任何位置访问此对象,使用process对象可以截获进程的异常.退出等事件,也可以获取进程的当前目录.环境变量.内存占用等信息,还可以执行进程退出.工作目录切换等 ...

  8. VMware vSphere克隆虚拟机

    参考资料:http://blog.csdn.net/shen_jz2012/article/details/48416771 1. 首先将你所要克隆的虚拟机关掉 2. 选择你的ESXI服务器     ...

  9. 关于Cookie跨域的问题

    Cookie是一个伟大的发明,它允许Web开发者保留他们的用户的登录状态.但是当你的站点有一个以上的域名时就会出现问题了.在Cookie规范上说,一个cookie只能用于一个域名,不能够发给其它的域名 ...

  10. AngulaJs -- 隔离作用域

    具有隔离作用域的指令最主要的使用场景是创建可复用的组件 创建具有隔离作用域的指令需要将scope属性设置为一个空对象{}.如果这样做了,指令的 模板就无法访问外部作用域了: <div ng-co ...