火车站 题解
题目背景
有一个奇奇怪怪的火车站,奇奇怪怪的站长JTZ想要解决一个奇奇怪怪的问题。
题目描述
现在有 \(N\) 列火车要进出站,对于同一列车进站和出站有且只有一次鸣笛,笛声有 \(1-M\) 种音调,要求相邻的两次鸣笛之间音调的差的绝对值不能小于 \(K\) (不鸣笛笛声音调看作\(1e100\) )。不然耳朵不好的车站管理员XYH分不清楚是哪一列车,现在XYH给出了每一列火车的进出,JTZ想知道总共有多少种鸣笛的方案,而他又不想太麻烦,所以只需要方案数除以 \(43621789\) 的余数。
某中学八年级大佬RSJ知道了这个消息后,觉得太简单了,几下算出了结果 \(x\) (取余数后)。于是他想让你算出 \(M^x \mod 43621789\) 。
输入格式
第一行三个整数 \(N,M,K\) 。
第二行有 \(2N\) 个整数,每个整数是 \(0\) 或 \(1\) 代表车进站和出站,保证数据合法,也就是说当车站没有车的时候没有车出站,最后车站没有车。
输出格式
一行,表示答案。( \(M^x \mod 43621789\) )
输入输出样例
输入#1
2 1 0
0 0 1 1
输出#1
1
输入#2
3 5 2
0 0 0 1 1 1
输出#2
40308287
提示/说明
图非常重要
样例解释:
样例1: \(x=4,M=1\) 答案为 \(1^4 \mod 43621789=1\)
样例2: \(x=250,M=5\) 答案为 \(5^{250} \mod 43621789=40308287\)
数据范围
本题采用 Subtask
\(\text{Subtask}\ 1\): 测试点 \(1-5\) \(30\%\) \(N\le 3,M\le 7\)
\(\text{Subtask}\ 2\): 测试点 \(6-12\) \(40\%\) \(N\le 100,M\le 7\)
\(\text{Subtask}\ 3\): 测试点 \(13-20\) \(40\%\) \(N\le 500,M\le 7\)
你只有通过每个 \(\text{Subtask}\) 的所有测试点才能获得该 \(\text{Subtask}\) 的分值。
题目解析
这道题目的出题灵感来自于CF149D。我们只要把火车进站看成左括号,火车出站看成右括号。其实应该是栈。
排列与组合是行不通的,因为对于同一列车进站和出站有且只有一次鸣笛,由于没有要求输出步骤,又可以搜索,考虑DP。无疑是区间DP,因为对于鸣笛的音调会影响到其他的方案数量,那么需要将左右侧的鸣笛音调列入方程转移式。
令函数 \(f(i,j,x,y)\) 为区间 \([i,j]\) 中,左右端点中,左端点的鸣笛音调为 \(x\) ,右端点的鸣笛音调为 \(y\) 的种数。不鸣笛记为 \(0\) 。分两种情况考虑。
我们需要预处理出辆火车的进出站,存在数组里,要求能 \(\Theta (1)\) 查询。
情况一:第 \(i\) \(j\) 次进出站时相同的车。
那么我们需要枚举 \(i,j\) 的音调以及相邻的 \(i+1,j-1\) 的音调,并且要保证数据合法。
其中 \(|a-x|\geq k\) 或者 \(x=0,a\not=0\) 或者 \(x\not=0,a=0\)
并且 \(|b-y|\geq k\) 或者 \(b=0,y\not=0\) 或者 \(b\not=0,y=0\)
并且 \(x=0,y\not=0\) 或者 \(x\not= 0,y\not= 0\)
情况二:第 \(i\) \(j\) 次进出站时不是相同的车。
设第 \(i\) 辆车的出站为 \(mid\) ,那么就可以将区间 \([i,j]\) 分割成区间 \([i,mid],[mid+1,j]\) ,然后枚举四个端点音调的即可,也要保证数据合法。
其中 \(|a-b|\geq x\) 或者 \(a=0,b\not=0\) 或者 \(a\not= 0,b=0\)
并且 \(x=0,a\not=0\) 且 \(x\not= 0,a=0\) (因为 \(x,a\) 同一辆车)
最后注意一些细节就可以了。
算法复杂度是 \(\Theta \left( N^2M^4+N\right)\) 的,虽然可以优化成 \(\Theta \left( N^2M^3+N\right)\) 但是因为我懒所以我就不写了。
最后记得输出 \(M^x \mod 43621789\) ,记得加上快速幂和 long long。