【cdq分治】HDOJ 5324 Boring Class
3420 ワード
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
", (int)vec.size());
for(int i = 0; i < vec.size(); i++) printf("%d%c", vec[i], i == (int)vec.size() - 1 ? '
' : ' ');
}
int main()
{
while(scanf("%d", &n) != EOF) {
work();
}
return 0;
}