[USACO19JAN]Train Tracking 2——神仙结论题+DP
原题链接
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\)那么有转移
\]
这样是\(O(nk)\)的,不可接受,于是用一个错位相消就可以得到一个可以\(O(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的更多相关文章
- P5204 [USACO19JAN]Train Tracking 2
P5204 [USACO19JAN]Train Tracking 2 毒毒题,对着嘤文题解看了贼久 首先考虑此题的一个弱化版本:如果输入的所有\(c_i\)相等怎么做 现在假设有\(len\)个数,取 ...
- 【bzoj3997】[TJOI2015]组合数学 Dilworth定理结论题+dp
题目描述 给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走.问至少走多少次才能将财宝捡完.此对此问题变形,假设每个格子中有好多财宝,而每一次经过一个格子至多只能捡走一块财宝,至少走 ...
- [USACO19JAN]Train Tracking 2 P
拿到本题后,可以观察到一个性质,如果出现了 \(c_i \ne c_{i + 1}\) 那么我们一定可以确定一个位置的值,这启示着我们将 \(c_i\) 相同的部分单独拿出来考虑再将最后的答案合并.于 ...
- [bzoj1369][Baltic2003]Gem_树形dp_结论题
Gem bzoj-1369 Baltic-2003 题目大意:给你一棵树,让你往节点上添自然数,使得任意相邻节点的数不同且使得权值最小. 注释:n为结点个数,$1\le n\le 10^3$. 想法: ...
- [codevs5578][咸鱼]tarjan/结论题
5578 咸鱼 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 在广袤的正方形土地上有n条水平的河流和m条垂直的河流,发达的咸鱼家族在m*n个河流交叉点都 ...
- BZOJ_1367_[Baltic2004]sequence_结论题+可并堆
BZOJ_1367_[Baltic2004]sequence_结论题+可并堆 Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 ...
- [BZOJ3609][Heoi2014]人人尽说江南好 结论题
Description 小 Z 是一个不折不扣的 ZRP(Zealot Round-game Player,回合制游戏狂热玩家), 最近他 想起了小时候在江南玩过的一个游戏. 在过去,人们是要 ...
- 【uoj#282】长度测量鸡 结论题
题目描述 给出一个长度为 $\frac{n(n+1)}2$ 的直尺,要在 $0$ 和 $\frac{n(n+1)}2$ 之间选择 $n-1$ 个刻度,使得 $1\sim \frac{n(n+1)}2$ ...
- 【uoj#175】新年的网警 结论题+Hash
题目描述 给出一张 $n$ 个点 $m$ 条边的无向连通图,每条边的边权为1.对于每个点 $i$ ,问是否存在另一个点 $j$ ,使得对于任意一个不为 $i$ 或 $j$ 的点 $k$ ,$i$ 到 ...
随机推荐
- 36.HTTP协议
HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...
- Bloom Filter布隆过滤器原理和实现(1)
引子 <数学之美>介绍布隆过滤器非常经典: 在日常生活中,包括设计计算机软件时,经常要判断一个元素是否在一个集合中.比如: 在字处理软件中,需要检查一个英语单词是否拼写正确(也就是要判断它 ...
- 使用Vue自定义指令实现Select组件
完成的效果图如下: 一.首先,我们简单布局一下: <template> <div class="select"> <div class="i ...
- [转帖]localectl
localectl http://linux.51yip.com/search/localectl localectl 命令简介. 相关命令:暂无相关命令 localectl — 控制系统的本地化与键 ...
- SSM框架的整合与使用——实现简单的转账系统
一.整合思路 SSM框架即SpringMVC + Spring + MyBati框架集,是一种轻量级的Web开源框架.它们各自在JAVA三层架构中负责的模块如下图所示: 其中,SpringMVC与Sp ...
- 在win下开发的项目怎么迁移到linux下面才能正常运行?
我可以直接拷贝项目目录到linux下面直接操作吗? 答案: 可以,咋可能??? 为啥??? win开发直接拷贝过去,你不凉谁凉了,我以前也同样的单纯,如果你项目里用的绝对路径! 那恭喜你,你凉了,清楚 ...
- spark异常篇-关闭程序
在运行 spark 程序时,出于某种原因,我想停止运行,狂按 ctrl+c 不一定起作用 以下两种情况是不好关闭的 1. cluster 运行模式 2. SparkStreaming 程序 本文旨在收 ...
- 适合新手的160个creakme(一)
先跑一下 直接使用这个字符串去check,发现提示信息有关键字符串 CODE:0042FB80 00000021 C Sorry , The serial is incorect ! 找到这个字符串的 ...
- mysql批量修改数据库表引擎
数据库表之前的引擎是MyISAM,影响事务操作,要改成Innodb引擎 查询表引擎 SELECT CONCAT(table_name,' ', engine) FROM information_sch ...
- javascript常用内置对象——Array对象
Array对象: 创建 Array 对象的语法: new Array(); new Array(元素个数); new Array(element0, element1, ..., elementn); ...