原题链接

orz xzz巨佬

首先发现一个结论:两个相邻的\(c\)值如果不相同的话,就可以固定某个位置的值了

这启示我们把连续且相等的\(c\)给单独拿出来看,也就是对于一些\(c_i=c_{i+1}=...=c_j=v\),能不能从中得出一些东西

这一段代表的区间总长为\(j-i+k\),所有的数都大于等于\(v\),同时每\(k\)个中就有至少一个\(v\),有一个比较显然的\(dp\):设\(f[i]\)表示最后一个\(v\)在\(i\)位置时的合法方案数,\(p\)为\(1e9-v\)那么有转移

\[f[i]=\sum\limits_{j=i-k}^{i-1}p^{i-j-1}f[j]
\]

这样是\(O(nk)\)的,不可接受,于是用一个错位相消就可以得到一个可以\(O(1)\)转移的式子

\[f[i]=(p+1)f[i-1]-p^k*f[i-k-1]
\]

其实上面这个式子也有实际意义,可以直接推出来

然后把这一段的\(c\)放到序列中看看,考虑它们左右的两个数\(c_{i-1}\)和\(c_{j+1}\)影响(\(a\)为原序列)

①如果\(c_{i-1}>c_i\),表明\(a_{i+k-1}=v\)且\(c_i~c_j\)中的前\(k-1\)个在前一段中已经被考虑过了,因此本次需要考虑的长度减少\(k-1+1=k\)个

②如果\(c_{j+1}>c_j\),表明\(a_{i-k+1}=v\)且\(c_i~c_j\)中的后\(k-1\)个在后一段中已经被考虑过了,因此本次需要考虑的长度也减少\(k-1+1=k\)个

这意味着我们只需要在\(i-j+k\)的基础上减掉几个\(k\)就可以将其化归到上一个模型上去了

具体实现的话,我们只需要找出所有的极大连续相等子段并把它们的贡献累乘起来就行了

代码

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <random>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <map>
#include <set> #define IINF 0x3f3f3f3f3f3f3f3fLL
#define u64 unsigned long long
#define pii pair<int, int>
#define mii map<int, int>
#define u32 unsigned int
#define lbd lower_bound
#define ubd upper_bound
#define INF 0x3f3f3f3f
#define vi vector<int>
#define ll long long
#define mp make_pair
#define pb push_back
#define is insert
#define se second
#define fi first
#define ps push #define $SHOW(x) cout << #x" = " << x << endl
#define $DEBUG() printf("%d %s\n", __LINE__, __FUNCTION__) using namespace std; #define MAXN 100000
#define MOD 1000000007 int n, k, c[MAXN + 5], f[MAXN + 5]; int fpow(int x, int p) {
int ret = 1;
while (p) {
if (p & 1) ret = 1LL * ret * x % MOD;
x = 1LL * x * x % MOD;
p >>= 1;
}
return ret;
} int solve(int v, int l) {
int p = 1000000000 - v, pk = fpow(p, k);
f[0] = f[1] = 1;
for (int i = 2; i <= l + 1; ++i) {
f[i] = 1LL * (p + 1) * f[i - 1] % MOD;
if(i - k - 1 >= 0) f[i] = (f[i] - 1LL * pk * f[i - k - 1] % MOD + MOD) % MOD;
}
return f[l + 1]; // 注意这里返回l+1而不是l,否则就会钦定a[l]为v了
} int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n - k + 1; ++i) scanf("%d", &c[i]);
int ans = 1;
for (int i = 1, j, len; i <= n - k + 1; i = j + 1) {
j = i;
while (c[j+1] == c[i]) j++;
len = j - i + k;
if (i != 1 && c[i - 1] > c[i]) len -= k;
if (j != n - k + 1 && c[j + 1] > c[i]) len -= k;
if (len > 0) ans = 1LL * ans * solve(c[i], len) % MOD;
}
printf("%d\n", ans);
return 0;
}

[USACO19JAN]Train Tracking 2——神仙结论题+DP的更多相关文章

  1. P5204 [USACO19JAN]Train Tracking 2

    P5204 [USACO19JAN]Train Tracking 2 毒毒题,对着嘤文题解看了贼久 首先考虑此题的一个弱化版本:如果输入的所有\(c_i\)相等怎么做 现在假设有\(len\)个数,取 ...

  2. 【bzoj3997】[TJOI2015]组合数学 Dilworth定理结论题+dp

    题目描述 给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走.问至少走多少次才能将财宝捡完.此对此问题变形,假设每个格子中有好多财宝,而每一次经过一个格子至多只能捡走一块财宝,至少走 ...

  3. [USACO19JAN]Train Tracking 2 P

    拿到本题后,可以观察到一个性质,如果出现了 \(c_i \ne c_{i + 1}\) 那么我们一定可以确定一个位置的值,这启示着我们将 \(c_i\) 相同的部分单独拿出来考虑再将最后的答案合并.于 ...

  4. [bzoj1369][Baltic2003]Gem_树形dp_结论题

    Gem bzoj-1369 Baltic-2003 题目大意:给你一棵树,让你往节点上添自然数,使得任意相邻节点的数不同且使得权值最小. 注释:n为结点个数,$1\le n\le 10^3$. 想法: ...

  5. [codevs5578][咸鱼]tarjan/结论题

    5578 咸鱼  时间限制: 1 s  空间限制: 128000 KB   题目描述 Description 在广袤的正方形土地上有n条水平的河流和m条垂直的河流,发达的咸鱼家族在m*n个河流交叉点都 ...

  6. BZOJ_1367_[Baltic2004]sequence_结论题+可并堆

    BZOJ_1367_[Baltic2004]sequence_结论题+可并堆 Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 ...

  7. [BZOJ3609][Heoi2014]人人尽说江南好 结论题

    Description 小 Z 是一个不折不扣的 ZRP(Zealot Round-game Player,回合制游戏狂热玩家), 最近他 想起了小时候在江南玩过的一个游戏.     在过去,人们是要 ...

  8. 【uoj#282】长度测量鸡 结论题

    题目描述 给出一个长度为 $\frac{n(n+1)}2$ 的直尺,要在 $0$ 和 $\frac{n(n+1)}2$ 之间选择 $n-1$ 个刻度,使得 $1\sim \frac{n(n+1)}2$ ...

  9. 【uoj#175】新年的网警 结论题+Hash

    题目描述 给出一张 $n$ 个点 $m$ 条边的无向连通图,每条边的边权为1.对于每个点 $i$ ,问是否存在另一个点 $j$ ,使得对于任意一个不为 $i$ 或 $j$ 的点 $k$ ,$i$ 到 ...

随机推荐

  1. js 数组遍历 对象遍历

    一.数组遍历 1,普通for循环,经常用的数组遍历 var arr = [1,2,0,3,9]; for ( var i = 0; i <arr.length; i++){ console.lo ...

  2. 洛谷 题解 UVA1626 【括号序列 Brackets sequence】

    看还没有人发记搜的题解,赶紧来水发一篇 我们定义dp[i][j]为区间i~j内最少添加几个括号才能把这个串变成正规括号序列. 考虑四种情况 i>j不存在这种子串,返回0 i==j子串长度为1无论 ...

  3. vue-cli3创建vue项目之vue.config.js配置

    module.exports = { // 基本路径 publicPath: '/', // 输出文件目录 outputDir: 'dist', // eslint-loader 是否在保存的时候检查 ...

  4. [转帖]中国新超算彻底告别进口CPU 国产芯片已可与国外抗衡

    中国新超算彻底告别进口CPU 国产芯片已可与国外抗衡 蓝天·2017-10-17·本土IC 来源: 观察者网 https://www.laoyaoba.com/html/news/newsdetail ...

  5. 解决redis运行期间key值过期但是内存memory依然占用过高

    要解决这个问题,首先要了解redis info信息中几个数据的意义:   used_memory:810575104 //数据占用了多少内存(字节)  used_memory_human:773.02 ...

  6. oracle共享数据库操作

    Hello,大家好,这个功能相信新手小白很需要,今天小编因为刚好遇到,所以写出来分享给大家,首先你电脑得有数据库,以及PLSQL工具包,这个相信大家都有了 1.打开NET Manger应用,win10 ...

  7. (二十五)JDBC多表查询

    java易错点 一对多 VS 多对一 VS 多对多 级联 多表增删改 多对多表设计语句(学生老师) java易错点 数组初始化的时候,可以用 {} 赋值,初始化以后,只能用 new Object[] ...

  8. 集成第三方框架,报错NoSuchFieldError:logger

    logger项目中使用springboot的版本是2.0.1.RELEASE,该版本依赖的spring版本为5.0.5.RELEASE (logger在spring版本5.0.7.RELEASE中), ...

  9. 第一章、web应用安全概论--web应用系统介绍--TCP/IP协议

    TCP/IP协议源于1969年,是国际互联网Internet采用的协议标准TCP/IP协议是一组通信协议的代名词,是由一系列协议组成的协议族,本身是指两个协议集:    TCP--传输控制协议    ...

  10. MySQL SQL Training

    源于知乎:50道SQL练习题 一.表数据 1.学生表——Student ),Sname ),Sage )); ' , '赵雷' , '1990-01-01' , '男'); ' , '钱电' , '1 ...