标签:front 顺时针 出现 单调队列 include 队列 题目 前缀和 没有
一个环形公路上总共有N个车站,每站都有若干升汽油(有的站可能油量为零),每升油可以让汽车行驶一千米。
从某个车站出发,一直按顺时针(或逆时针)方向走遍所有的车站,并回到起点。
在一开始的时候,汽车内油量为零,每到一个车站就把该站所有的油都带上(起点站亦是如此),行驶过程中不能出现没有油的情况。
判断以每个车站为起点能否按条件成功周游一周。
每个站油量减去到下一个站的距离即每个站的净得油量。
进行前缀和可以求出到这个站累计用油量。
每个环中,判断这个区间的最小累计用油量是否为负数(即不满足条件)。
对于多个起点,发现所求前缀和是一个编号累加的东西,可以用单调队列优化。
#include <deque>
#include <cstdio>
#define int long long
std::deque<int> q;
int n;
int b[2000001], a[2000001], ans[2000001];
signed main() {
scanf("%lld", &n);
for (int i = 1, x, y; i <= n; i++) {
scanf("%lld %lld", &x, &y);
a[i + n] = a[i] = x - y;
int d = n - i == 0 ? n : n - i;
b[d + n] = b[d] -= y;
b[2 * n - i + 1] = b[n - i + 1] += x;
}
for (int i = 2; i <= n * 2; i++)
a[i] += a[i - 1], b[i] += b[i - 1];
for (int i = 1; i < n * 2; i++) {
while (q.size() && i - q.front() + 1 > n)
q.pop_front();
while (q.size() && a[i] <= a[q.back()])
q.pop_back();
q.push_back(i);
if (i >= n) {
if (a[q.front()] - a[i - n] >= 0)
ans[i - n + 1] = 1;
}
}
q.clear();
for (int i = 1; i < n * 2; i++) {
while (q.size() && i - q.front() + 1 > n)
q.pop_front();
while (q.size() && b[i] <= b[q.back()])
q.pop_back();
q.push_back(i);
if (i >= n) {
if (b[q.front()] - b[i - n] >= 0)
ans[2 * n - i] = 1;
}
}
for (int i = 1; i <= n; i++)
if (ans[i])
printf("TAK\n");
else
printf("NIE\n");
}
标签:front 顺时针 出现 单调队列 include 队列 题目 前缀和 没有
原文地址:https://www.cnblogs.com/HSZGB/p/14728819.html