cdq分治加树状数组就可以了
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 50005 #define maxm 10000005 #define eps 1e-7 #define mod 1000000007 #define INF 0x3f3f3f3f #define PI (acos(-1.0)) #define lowbit(x) (x&(-x)) #define mp make_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R #define pii pair<int, int> #pragma comment(linker, "/STACK:16777216") typedef long long LL; typedef unsigned long long ULL; //typedef int LL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} // head int tree[maxn]; int yy[maxn]; int dp[maxn]; struct node { int x, y, id; node(int x = 0, int y = 0, int id = 0) : x(x), y(y), id(id) {} }tp[maxn]; vector<int> vec; pii p[maxn]; int ta[maxn]; int tb[maxn]; int n, m; void add(int x, int v) { for(int i = x; i > 0; i -= lowbit(i)) tree[i] = max(tree[i], v); } int query(int x, int N) { int res = 0; for(int i = x; i <= N; i += lowbit(i)) res = max(res, tree[i]); return res; } int cmp(node a, node b) { if(a.x != b.x) return a.x < b.x; else if(a.y != b.y) return a.y > b.y; else return a.id < b.id; } void cdq(int L, int R) { if(L == R) { dp[L]++; return; } int mid = (L + R) >> 1; cdq(mid+1, R); int cnt = 0; for(int i = L; i <= R; i++) { yy[++cnt] = p[i].second; tp[cnt] = node(p[i].first, p[i].second, i); } sort(yy+1, yy+cnt+1); int tcnt = unique(yy+1, yy+cnt+1) - yy - 1; for(int i = 1; i <= cnt; i++) tp[i].y = lower_bound(yy+1, yy+tcnt+1, tp[i].y) - yy; for(int i = 1; i <= cnt; i++) tree[i] = 0; sort(tp+1, tp+cnt+1, cmp); for(int i = 1; i <= cnt; i++) { if(tp[i].id <= mid) dp[tp[i].id] = max(dp[tp[i].id], query(tp[i].y, cnt)); else add(tp[i].y, dp[tp[i].id]); } cdq(L, mid); } void work() { for(int i = 1; i <= n; i++) scanf("%d", &ta[i]); for(int i = 1; i <= n; i++) scanf("%d", &tb[i]); for(int i = 1; i <= n; i++) p[i] = mp(ta[i], tb[i]); memset(dp, 0, sizeof dp); cdq(1, n); int ans = 0; for(int i = 1; i <= n; i++) ans = max(ans, dp[i]); vec.clear(); int pos = 1, tx = INF, ty = -INF; for(int k = 1; k <= ans; k++) { int tt = ans - k + 1; for(int i = pos; i <= n; i++) if(dp[i] == tt && p[i].first <= tx && p[i].second >= ty) { pos = i+1; tx = p[i].first; ty = p[i].second; vec.push_back(i); break; } } printf("%d\n", (int)vec.size()); for(int i = 0; i < vec.size(); i++) printf("%d%c", vec[i], i == (int)vec.size() - 1 ? '\n' : ' '); } int main() { while(scanf("%d", &n) != EOF) { work(); } return 0; }