萌新求助cdq分治+dp
查看原帖
萌新求助cdq分治+dp
106738
_Felix楼主2021/7/14 20:36

写挂了,30分,每个输出答案都比正确答案大。

#include<bits/stdc++.h>
using namespace std;
#define mkp make_pair
#define pb push_back
typedef long long ll;
const int N = 2e5 + 10, inf = 0x3f3f3f3f;
int n, m, tr[N], dp[N], lsh[N];

struct node{
	int val, l, r, id;
}num[N], tmp[N];

bool cmp(node a, node b){ return a.val < b.val; }
bool cmp2(node a, node b){ return a.l < b.l; }
bool cmp3(node a, node b){ return a.id < b.id; }

int lowbit(int x){ return x & -x; }
void insert(int x, int val){ for(; x <= 200000; x += lowbit(x)) tr[x] = max(tr[x], val); }
int query(int x){ int ret = 0; for(; x; x -= lowbit(x)) ret = max(tr[x], ret); return ret; }
void recover(int x){ for(; x <= 200000; x += lowbit(x)) tr[x] = -inf; }

void cdq(int L, int R){
	if(L == R) return;
	int mid = (L + R) >> 1;
	
	cdq(L, mid);
//	memset(tr, 0, sizeof(tr));
	for(int i = L; i <= R; i++) tmp[i] = num[i];
	sort(tmp + L + 1, tmp + mid + 1, cmp);
	sort(tmp + mid + 2, tmp + R + 1, cmp2);
	
	int pos = L;
	for(int i = mid + 1; i <= R; i++){
		while(pos <= mid && tmp[pos].val <= tmp[i].l)
			insert(tmp[pos].r, dp[tmp[pos].id]), pos++;
		dp[tmp[i].id] = max(dp[tmp[i].id], query(tmp[i].val) + 1);
	}
	for(int i = L; i < pos; i++) recover(tmp[pos].r);
	
	cdq(mid + 1, R);
	return;
}

int main(){
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= 100000; i++) tr[i] = -inf;
	for(int i = 1; i <= n; i++)
		scanf("%d", &num[i].val), num[i].id = i, num[i].l = num[i].r = num[i].val, lsh[i] = num[i].val;
	for(int i = 1, x, y; i <= m; i++){
		scanf("%d%d", &x, &y); lsh[n + i] = y; 
		num[x].l = min(num[x].l, y);
		num[x].r = max(num[x].r, y);
	}
	sort(lsh + 1, lsh + n + m + 1);
	int len = unique(lsh + 1, lsh + n + m + 1) - lsh - 1;
	for(int i = 1; i <= n; i++){
		num[i].val = lower_bound(lsh + 1, lsh + len + 1, num[i].val) - lsh;
		num[i].l = lower_bound(lsh + 1, lsh + len + 1, num[i].l) - lsh;
		num[i].r = lower_bound(lsh + 1, lsh + len + 1, num[i].r) - lsh;
	}
	for(int i = 1; i <= n; i++) dp[i] = 1;
	cdq(1, n);
	int ans = 0;
	for(int i = 1; i <= n; i++) ans = max(ans, dp[i]);
	printf("%d\n", ans);
	return 0;
}
2021/7/14 20:36
加载中...