[DP][CDQ分治] BZOJ 4553: [Tjoi2016&Heoi2016]序列
2018-03-03 13:52
609 查看
SolutionSolution
设位置ii最大可变成riri,最小lili。fifi为ii位置的答案。容易得到fi=max{fj+1|j<i,rj≤ai,aj≤li}fi=max{fj+1|j<i,rj≤ai,aj≤li}把(rj,aj)(rj,aj)当作二位平面的一个点,((ai,li),(0,0))((ai,li),(0,0))看作一个矩形。
就是一个类似二维数点的问题。
直接CDQCDQ分治就好了。
O(nlog2n)O(nlog2n)
#include <bits/stdc++.h> #define show(x) cerr << #x << " = " << x << endl using namespace std; typedef long long ll; typedef pair<int, int> Pairs; const int N = 202020; inline char get(void) { static char buf[100000], *S = buf, *T = buf; if (S == T) { T = (S = buf) + fread(buf, 1, 100000, stdin); if (S == T) return EOF; } return *S++; } template<typename T> inline void read(T &x) { static char c; x = 0; int sgn = 0; for (c = get(); c < '0' || c > '9'; c = get()) if (c == '-') sgn = 1; for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0'; if (sgn) x = -x; } int n, m, q, x, y, clc; int mx , vis ; int a , l , r ; int f ; struct cpp { int x, y, z, id, tp; cpp(int _x = 0, int _y = 0, int _z = 0, int i = 0, int t = 0): x(_x), y(_y), z(_z), id(i), tp(t) {} inline bool operator <(const cpp &b) const { return x < b.x; } }; cpp b ; inline void update(int x, int a) { for (x; x <= m; x += x & -x) if (vis[x] != clc) { mx[x] = a; vis[x] = clc; } else mx[x] = max(mx[x], a); } inline int query(int x) { int mx = 0; for (; x; x -= x & -x) if (vis[x] == clc) mx = max(mx, ::mx[x]); return mx; } inline void divAndConq(int l, int r) { static cpp tmp ; if (l == r) return; int mid = (l + r) >> 1; int s1 = l, s2 = mid + 1; for (int i = l; i <= r; i++) if (b[i].z <= mid) tmp[s1++] = b[i]; else tmp[s2++] = b[i]; for (int i = l; i <= r; i++) b[i] = tmp[i]; divAndConq(l, mid); ++clc; int j = l; for (int i = mid + 1; i <= r; i++) { for (; j <= mid && b[j].x <= b[i].x; j++) if (b[j].tp == 0) update(b[j].y, f[b[j].id]); if (b[i].tp == 1) f[b[i].id] = max(f[b[i].id], query(b[i].y) + 1); } divAndConq(mid + 1, r); int s = l; s1 = l; s2 = mid + 1; while (s1 <= mid && s2 <= r) if (b[s1] < b[s2]) tmp[s++] = b[s1++]; else tmp[s++] = b[s2++]; while (s1 <= mid) tmp[s++] = b[s1++]; while (s2 <= r) tmp[s++] = b[s2++]; for (int i = l; i <= r; i++) b[i] = tmp[i]; } int main(void) { freopen("1.in", "r", stdin); freopen("1.out", "w", stdout); read(n); read(q); for (int i = 1; i <= n; i++) { read(a[i]); f[i] = 1; l[i] = r[i] = a[i]; } while (q--) { read(x); read(y); l[x] = min(l[x], y); r[x] = max(r[x], y); } for (int i = 1; i <= n; i++) m = max(r[i], m); q = 0; for (int i = 1; i <= n; i++) { b[++q] = cpp(a[i], l[i], q, i, 1); b[++q] = cpp(r[i], a[i], q, i, 0); } sort(b + 1, b + q + 1); divAndConq(1, q); cout << *max_element(f + 1, f + n + 1); return 0; }
相关文章推荐
- [bzoj4553][Tjoi2016&Heoi2016]序列 cdq分治
- 【bzoj4553】【TJOI2016&HEOI2016】【序列】【cdq分治+树状数组】
- [BZOJ4553][TJOI2016&&HEOI2016]序列(CDQ分治)
- BZOJ 4553 [Tjoi2016&Heoi2016]序列 ——CDQ分治 树状数组
- [Tjoi2016&Heoi2016]【BZOJ 4553】【JZOJ 4606】序列
- BZOJ 4553: [Tjoi2016&Heoi2016]序列
- [BZOJ4553][HEOI2016]序列 CDQ分治
- cdq分治——bzoj4553: [Tjoi2016&Heoi2016]序列
- bzoj4553 [Tjoi2016&Heoi2016]序列
- bzoj 4553: [Tjoi2016&Heoi2016]序列 (CDQ分治+DP+树状数组)
- Bzoj4553: [Tjoi2016&Heoi2016]序列
- Bzoj4553: [Tjoi2016&Heoi2016]序列
- BZOJ 4553 [Tjoi2016&Heoi2016]序列
- BZOJ 4553: [Tjoi2016&Heoi2016]序列
- [BZOJ4553][Tjoi2016&Heoi2016]序列 cdp分治+dp
- BZOJ 4553: [Tjoi2016&Heoi2016]序列
- 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组
- BZOJ 4553 Tjoi2016&Heoi2016 序列
- bzoj 4553: [Tjoi2016&Heoi2016]序列 cdq分治+树状数组
- bzoj 4553: [Tjoi2016&Heoi2016]序列