测温
这道题好独特,本来以为是贪心+单调栈之类的。。后来想了下发现有个信息完全不知道怎么维护,下面是整理dls的思路。
考虑一个比较暴力的方法,
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]为考虑到第i天,当前温度为j时,连续的最长天数,所以我们有这样的转移
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
k
]
+
1
,
k
<
=
j
dp[i][j] = dp[i - 1][k]+1, k <= j
dp[i][j]=dp[i−1][k]+1,k<=j
这个dp的时间复杂度为
O
(
n
∗
W
)
O(n*W)
O(n∗W)
再仔细观察,发现这样一件事情:如果若 j > = k j >= k j>=k,有 d p [ i ] [ j ] > = d p [ i ] [ k ] dp[i][j] >= dp[i][k] dp[i][j]>=dp[i][k],因为小的满足,大的肯定也满足。
so?有了上面的性质,就知道 d p [ i ] [ j ] dp[i][j] dp[i][j]里面肯定是维护了一堆连续单调的数字,且包含这些值这些区间都是连续的。
所以我们可以把第二维去掉,用一个队列来维护这些离散的区间!
当 d p [ i − 1 ] [ j ] dp[i-1][j] dp[i−1][j]维护的r要大于当前的r时,我们把多余的部分弹出这个区间
情况1:
dp[i - 1][j], l1-------------- r1
l[i], r[i] l2---------r2
dp[i][j]变成这样
l2-----l1--r2
情况2
dp[i - 1][j], l1-------------- r1
l[i], r[i] l2---------r2
dp[i][j]变成这样
l2-----r1--r2
对于能由上一个转移来的区间,直接+1,多余部分弹出队列,而新增的部分,直接为1即可。这一部分用一个双端队列维护即可
如果可以转移,那么这意味对队列里面的一些小区间都+1,对于队列里面区间的val都加1的这个操作,我们可以维护一个全局加的数字S,每次我们加入一个新的值时,需要减去这个全局偏移(我也是对拍搞了很久才找到这个bug)。真实值为val+S
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N = 1e6 + 10, M = N + N, P = 131, INF = 1e9 + 10;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
using tp = tuple<int,int,int>;
bool muti = false;
int n, m;
struct Range
{
int l, r, val;
};
void solve() {
scanf("%d", &n);
deque<Range> q;
int S = 0; //全局偏移
int res = 0;
for(int i = 0; i < n; i++) {
int l, r;
scanf("%d%d", &l, &r);
//可以继承i-1的情况
if(q.size() && r >= q.front().l) {
//先弹出无法转移的
while(q.size() && q.back().l > r) q.pop_back();
//最后一段满足的设置为r, 最后一段的r设置为r
if(q.size()) q.back().r = r;
//处理左半的区间
if(q.front().l > l) {
//特别注意这里的值是 0-S = -S
q.push_front({l, q.front().l - 1, -S});
}
else {
while(q.size() && q.front().r < l) q.pop_front();
if(q.front().l < l) q.front().l = l;
}
S++;
}
else {
q.clear();
q.push_back({l, r, 1});
S = 0;
}
res = max(res, q.back().val + S);
}
cout << res << endl;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("E.txt", "r", stdin);
#endif
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T = 1;
if(muti) cin >> T;
while (T--) solve();
return 0;
}