原题链接

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. 【转】MySql 三大知识点——索引、锁、事务

    索引 索引,类似书籍的目录,可以根据目录的某个页码立即找到对应的内容. 索引的优点:1. 天生排序.2. 快速查找. 索引的缺点:1. 占用空间.2. 降低更新表的速度. 注意点:小表使用全表扫描更快 ...

  2. (模板)poj2387(dijkstra+优先队列优化模板题)

    题目链接:https://vjudge.net/problem/POJ-2387 题意:给n个点(<=1000),m条边(<=2000),求结点n到结点1的最短路. 思路:dijkstra ...

  3. 数据库学习其一 oracle11g数据泵导入导出

    一.检查环境一致性 需检查数据库客户端与服务端字符编码,以避免后续各种各样的问题 查询服务端编码 注意最好用sqlplus查询,用plsql有时候会出现查询不一致问题,如下图同一个语句在plsql和s ...

  4. oracle中表记录被另一个用户锁住

    应用场景 在查询oracle表时,提示表记录被另一个用户锁住了 有可能是在使用了pl/sql工具后修改某个表记录时,加锁,或者发生故障异常退出,下次登录进去修改不了 查询锁 --查看数据库的锁的来源. ...

  5. Maven仓库介绍以及私服搭建

      1 什么是Maven? 1.1 Maven的概念 Maven主要服务于基于Java平台的项目构建.依赖管理和项目信息开发,它是一个异常强大的构建工具,能够帮助我们自动化构建过程,从清理.编译.测试 ...

  6. Spark Scala当中reduceByKey的用法

    [学习笔记] /*reduceByKey(function)reduceByKey就是对元素为KV对的RDD中Key相同的元素的Value进行function的reduce操作(如前所述),因此,Ke ...

  7. 洛谷P2178 [NOI2015]品酒大会 后缀数组+单调栈

    P2178 [NOI2015]品酒大会 题目链接 https://www.luogu.org/problemnew/show/P2178 题目描述 一年一度的"幻影阁夏日品酒大会" ...

  8. Python 【Debug排除程序故障】

    debug #排除程序故障 print()函数常和#号注释结合在一起用来debug 多行注释有两种快捷操作:1.在需要注释的多行代码块前后加一组三引号''' 2.选中代码后使用快捷键操作:Window ...

  9. hdu 1506 最大子矩阵面积

    //写动态规划的题目 要把主要问题提炼出来 这里的问题就是求area=(j-k+1)*a[i]  如果找到j k是解决这个题目的关键 这里暴力求肯定是要超时的 这里用dp来优化 #include< ...

  10. aspectcore 简单解析

    .netcore 下aspectcore  的使用 动态代理: static void Main(string[] args) { Console.WriteLine("Hello Worl ...