例题8-8 防线(Defense Lines, ACM/ICPC CERC 2010, UVa1471)

来源:互联网 发布:linux统计目录文件数 编辑:程序博客网 时间:2024/05/11 13:02
1. 容易想到,预处理i开头与结尾的最大长度,枚举i,j的n方做法。
2. 优化在于已知i如何快速寻找一个j。
3. 考虑一种情形,a1 <= a2 && g1 => g2,显然可以舍去后者。
4. 那么我们用set维护(a, g),在加入时不断舍去冗余,这也是一种单调的思想。
5. 可以发现在set中,a最大的g也一定最大,即对于此时i的最优解。
#include <set>#include <map>#include <ctime>#include <cmath>#include <stack>#include <queue>#include <deque>#include <cstdio>#include <string>#include <vector>#include <cctype>#include <sstream>#include <utility>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#define SF(a) scanf("%d", &a)#define PF(a) printf("%d\n", a)  #define SFF(a, b) scanf("%d%d", &a, &b)  #define SFFF(a, b, c) scanf("%d%d%d", &a, &b, &c)#define SFFFF(a, b, c, d) scanf("%d%d%d%d", &a, &b, &c, &d)#define CLEAR(a, b) memset(a, b, sizeof(a))#define IN() freopen("in.txt", "r", stdin)#define OUT() freopen("out.txt", "w", stdout)#define FOR(i, a, b) for(int i = a; i < b; ++i)#define LL long long#define maxn 200005#define maxm 205#define mod 1000000007#define INF 10000007#define eps 1e-4using namespace std;int buf[20], l;int read() {int x = 0; char ch = getchar(); bool f = 0;while (ch < '0' || ch > '9') { if (ch == '-') f = 1; ch = getchar(); }while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();return f ? -x : x;}void write(int x) {if (!x) { putchar(48); return; }l = 0; if (x < 0) putchar('-'), x = -x;while (x) buf[++l] = x % 10, x = x / 10;while (l) putchar(buf[l--] + 48);}//-------------------------CHC------------------------------//struct Node {int a, g;Node(int a, int g ): a(a), g(g) { }bool operator<(const Node &rhs) const { return a < rhs.a; }};set<Node> s;int a[maxn], g[maxn], f[maxn];int main() {int T;T = read();while (T--) {s.clear();int n;n = read();FOR(i, 0, n) a[i] = read();g[0] = 1;FOR(i, 1, n) {if (a[i] > a[i - 1]) g[i] = g[i - 1] + 1;else g[i] = 1;}f[n - 1] = 1;for (int i = n - 2; i >= 0; --i) {if (a[i] < a[i + 1]) f[i] = f[i + 1] + 1;else f[i] = 1;}int ans = 1;s.insert(Node(a[0], g[0]));FOR(i, 1, n) {Node cur(a[i], g[i]);set<Node>::iterator it = s.lower_bound(cur);bool ok = true;if (it != s.begin()) {if (it != s.end() && it->a == cur.a && it->g >= cur.g) ok = false;ans = max(ans, f[i] + (--it)->g);if (it->g >= cur.g) ok = false;}if (ok) {s.erase(cur);s.insert(cur);it = s.upper_bound(cur);while (it != s.end() && it->g <= cur.g) s.erase(it++);}}write(ans); puts("");}return 0;}

阅读全文
0 0