首页 > 其他分享 >题解:P3266 [JLOI2015] 骗我呢

题解:P3266 [JLOI2015] 骗我呢

时间:2024-08-25 21:04:36浏览次数:11  
标签:reflect JLOI2015 P3266 int 题解 a1 a2 dp mod

题意

有一个 \(n \times m\) 的数组 \(x_{i,j} (1 \le i \le n, 1 \le j \le m)\),满足:

  • \(x_{i,j}\in[0,m]\)

  • \(\forall i \in [1,n],\forall j\in[1,m),x_{i,j}<x_{i,j+1}\)

  • \(\forall i \in (1,n],\forall j\in[1,m),x_{i,j} <x_{i-1,j+1}\)

求可能的数组 \(x_{i,j}\) 的解数,答案对 \(10^9+7\) 取模。

分析

首先根据 \(x_{i, j} < x_{i,j+1}\) 得到 \(i\) 相同的一行 \(m\) 个元素是单调上升的。

又因为 \(x_{i,j}\in[0,m]\),所以这一行就是 \(0 \sim m\) 的序列中去掉一个元素。


考虑使用 dp。

令 \(dp_{i,j}\) 为第 \(i\) 行去掉元素 \(j\) 的解数。

模拟过程可得若第 \(i\) 行去除元素 \(j\),那么第 \(i-1\) 行可以去除 \([0,j+1]\) 中的任一元素。

所以得到转移方程:

\[\begin{align} dp_{i,j}&=\sum^{j+1}_{k=0} dp_{i-1,k}\\ &=\sum^{j}_{k=0} dp_{i-1,k}+dp_{i-1, j+1} \\ &=dp_{i, j-1}+dp_{i-1,j+1} \end{align} \]

答案即为 \(\sum^m_{k=0}\limits dp_{n,k}=dp_{n+1,m-1}\)。

转移过程如下(\(n=3,m=4\)):

我们将这个图像拉伸,平移一下:

发现就是求从 \((0,0)\) 到 \((n+m-1,n)\) 且只能向上和向右与直线 \(l_1:y=x+2\) 和直线 \(l_2:y=x-m-1\) 不交的路径数。


考虑使用反射容斥。

由容斥得:答案为总方案数 - 经过 \(l_1\) - 经过 \(l_2\) + 经过 \(l_1l_2\) + 经过 \(l_2l_1\) - 经过 \(l_1l_2l_1\) - 经过 \(l_2l_1l_2\)...

考虑如何计算每一部分。

已知从点 \((0,0)\) 到 \((n, m)\) 只能向上和向右的路径数为 \(\binom{n+m}{n}\)。

总方案数为原点到到 \((n+m-1,n)\) 的方案数。

经过 \(l_1\) 的方案数为原点到目标点 \(A\) 沿 \(l_1\) 对称得到的 \(A'\) 的方案数。

经过 \(l_1l_2\) 的方案数如何求解?

\(l_1\) 沿 \(l_2\) 对称得到直线 \(l_1'\)。

将 \(A'\) 沿 \(l_1'\) 对称得到 \(A''\)。

方案数即为原点到 \(A''\) 的方案数。


若某次对称得到的点 \(A_x\) 不在第一象限,那么结束循环。

Code

#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define maxn 4000006

int pre[maxn], inv[maxn];
int64_t ksm(int64_t x, int l)
{
    int64_t ret=1;
    for(;l;l>>=1, x=x*x%mod)
        if(l&1) ret=ret*x%mod;
    return ret;
}

int C(int n, int m) {return ((int64_t)pre[n]*inv[n-m]%mod)*inv[m]%mod;}

typedef pair<int, int> pos_t;
int path_count(pos_t p) {return C(p.first+p.second, p.first);}
pos_t reflect(int a, pos_t p) {return {p.second-a, a+p.first};}
int reflect(int a, int b) {return (a<<1)-b;}

int main()
{
    pre[0]=1;
    for(int i=1;i<maxn;i++) pre[i]=(int64_t)pre[i-1]*i%mod;
    inv[maxn-1]=ksm(pre[maxn-1], mod-2);
    for(int i=maxn-2;~i;i--) inv[i]=(int64_t)inv[i+1]*(i+1)%mod;
    int n, m;
    cin>>n>>m;
    int a1=2, a2=-m-1;
    int mul=-1, ans=path_count({n+m-1, n});
    for(pos_t p=reflect(a1, {n+m-1, n});p.first>=0&&p.second>=0;)
    {
        ans=((ans+mul*path_count(p))%mod+mod)%mod;
        a2=reflect(a1, a2);
        swap(a1, a2);
        p=reflect(a1, p);
        mul*=-1;
    }
    mul=-1;
    a1=-m-1, a2=2;
    for(pos_t p=reflect(a1, {n+m-1, n});p.first>=0&&p.second>=0;)
    {
        ans=((ans+mul*path_count(p))%mod+mod)%mod;
        a2=reflect(a1, a2);
        swap(a1, a2);
        p=reflect(a1, p);
        mul*=-1;
    }
    cout<<ans;
}

标签:reflect,JLOI2015,P3266,int,题解,a1,a2,dp,mod
From: https://www.cnblogs.com/redacted-area/p/18379561

相关文章

  • 题解:CF70D Professor's task
    题意实现以下两种操作:往点集\(S\)中添加一个点\((x,y)\)。询问点\((x,y)\)是否在点集\(S\)的凸包中。分析动态凸包板子。建议先完成P2521[HAOI2011]防线修建。上题维护的是上半个凸包,本题维护上下两个。将凸包中的点按\(x\)排序,通过\((x,y)\)前驱......
  • 题解:P2521 [HAOI2011] 防线修建
    题意给定若干个点,实现下列操作:删除一个点。查询上凸包的周长。分析建议先完成【模板】二维凸包。对于这个删除操作,我们没有好的方法去在线维护它。考虑离线询问。这样删除操作就变成了插入操作。插入一个新点有如下两种情况:新点在凸包内。新点在凸包外。我们回忆......
  • 题解:CF235C Cyclical Quest
    题意给定一个主串\(S\)和\(n\)个询问串,求每个询问串的所有循环同构在主串中出现的次数总和。分析后缀自动机好题。循环同构的过程可以看作从该串的头部删除一个字符,并在尾部加入一个字符。在后缀自动机上,跳parent树的过程就相当于删除头部的若干个字符。所以我们可......
  • 7z解压crc错误_7-Zip - 常见问题解答
    7z解压crc错误_7-Zip-常见问题解答7z解压crc错误_7-Zip-常见问题解答1.引言1.17-Zip简介1.2CRC错误概述2.7z文件和CRC错误2.1什么是7z文件2.2CRC错误的定义2.3CRC错误对文件的影响3.常见原因分析3.1文件传输过程中的错误3.2存储介质的损坏3.3不兼容的压......
  • 题解:P5680 [GZOI2017] 共享单车
    题目分析出题人是擅长隐藏题意的建树首先给你一张无向图,然后指定一个根节点\(k\),从根节点开始沿最短路到每一个节点。如果到某个节点有多条最短路径,选择上一个节点编号最短的。考虑记录前驱的Dijkstra。namespaceDJ{intdis[maxn],pre[maxn],val[maxn],vis[maxn]......
  • 题解:SP22382 ETFD - Euler Totient Function Depth
    题目链接:link,点击这里喵。前置知识:【模板】线性筛素数,欧拉函数,点击这里喵。题意简述:给定整数$l,r,k$,求出$[l,r]$中有多少个整数不断对自己取欧拉函数刚好$k$次结果为$1$。思路:看眼数据范围,$10^{10}$的量级显然不容我们每次暴力,故考虑预处理$\varphi(i),can(i,k),su......
  • 【面试系列】大数据平台常见面试题解答
    欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏:工......
  • AtCoder ABC 368题解
    前言本题解部分思路来自于网络。A-Cut题目大意有\(n\)张卡片叠在一起,从上到下给出\(n\)卡片的编号,将\(k\)张卡片从牌堆底部放到顶部后,从上到下输出卡片的编号。解题思路按照题意模拟即可。code#include<bits/stdc++.h>usingnamespacestd;inta[105];intmai......
  • SP666 VOCV - Con-Junctions 题解
    注意到这个问题具有最优子结构性,考虑树上dp。记$dp[i][0/1]$表示i号节点不放灯或放灯的最小值,$s[i][0/1]$为对应的方案数。那么我们可以进行如下转移:$dp[u][0]=\sum_{u->v}dp[v][1]$$dp[u][1]=\sum_{u->v}\min(dp[v][0],dp[v][1])$在更新对应的dp数组时,我们用......
  • P9482 [NOI2023] 字符串 题解
    题目描述\(T\)组数据,给定长为\(n\)的字符串\(s\),\(q\)次询问,给定\(i,r\),求有多少个\(l\)满足:\(1\lel\ler\)。\(s[i:i+l-1]\)字典序小于\(R(s[i+l:i+2l-1])\)。数据范围\(1\leT\le5,1\len,q\le10^5,1\lei+2r-1\len\)。时间限制\(\texttt{1s}\),......