Jump and Treasure (单调队列优化DP+调和级数)
题目大意:
一个数列,每一次可以跳P以内的距离,数列是有正有负,问跳到后面去的最大值, 有Q次询问,问 leve i, 每次只能跳 i 的倍数, n 10^6, q为 10^6次放
- 由简单到困难的思想
- 先考虑 leve 1的情况
- 显然这个东西可以用单调队列优化DP
- 而其他leve k可以 要弄的数 n/k个
- 更具查询来做是要爆的
- 预处理出
(调和级数)
就行了
后记:
- 单调队列: 一个队列存是单调的, 而且开头是在那个范围内,并且 加入数的时候,如果比后面的优,就进去,并且要删除后面的数,应为他比后面的数在后面,一定是比他们更在那个范围内
- 时间复杂度: 每一个数只会进队出队1次 是 O(n)的
- 调和级数 复杂度是 nlogn

#include <bits/stdc++.h> using namespace std; #define M 2000005 #define ri register int int n,m; int p[M]; int qu[M]; int main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); scanf("%d%d",&n,&m); for(ri i=1;i<=n;i++) scanf("%d",&p[i]); int l=1,r=1;qu[1]=1;cout<<0<<endl; for(ri i=2;i<=n;i++) { while(qu[l]<i-m) l++; 处理: while(p[qu[r]]>=p[i]&&r>=l) r--;qu[++r]=i;(插入) } }