[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$ 到 ...
随机推荐
- 最新 网龙网络java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.网龙网络等10家互联网公司的校招Offer,因为某些自身原因最终选择了网龙网络公司.6.7月主要是做系统复习.项目复盘.Le ...
- 最新 快乐阳光java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.快乐阳光等10家互联网公司的校招Offer,因为某些自身原因最终选择了快乐阳光.6.7月主要是做系统复习.项目复盘.Leet ...
- CentOS7 安装mysql(YUM源方式)
1.下载mysql源安装包 $ wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm 2.安装mysql ...
- PostgreSQL 修改设置数据库的默认用户以及权限.
1. 登录PG数据库. psql -U postgres 界面效果为: [root@centos76 ~]# psql -U postgres psql (10.7) Type "help& ...
- Python实现二叉树的非递归先序遍历
思路: 1. 使用列表保存结果: 2. 使用栈(列表实现)存储结点: 3. 当根结点存在,保存结果,根结点入栈: 4. 将根结点指向左子树: 5. 根结点不存在,栈顶元素出栈,并将根结点指向栈顶元素的 ...
- Linux系列(12)之例行工作调度
你知道工作调度有哪几种吗? 你知道在进行工作调度时需要哪些服务在运行吗? 你知道突发性工作调度的指令at的用法吗? 知道如何管理at的工作调度吗? 知道at指令进行工作调度的原理吗? 知道什么是背景任 ...
- Docker的安装和学习
dockers学习 2019年2月23日开始 docker系统要求 centos 7 核心为3.1以上 centos6.5以上 核心为 2.6以上 ...
- 【Python基础】13_Python中的PASS
pass关键字的使用 在程序分支中,如果不想立刻执行该分支,可使用pass占位符,pass不表示任何含义,仅保证程序不会报错. 如: action_str = input("请选择希望执行的 ...
- easyui datagrid 合并相同行
$.extend($.fn.datagrid.methods, { autoMergeCells: function (jq, fields) { return jq.each(function () ...
- 浅谈hashcode
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...