HDU 다중 학교 여섯 번째 1,002 말도 시간 - LIS 삭제 점

주제 링크 : 포인트 I 아 ╭ (╯ ^ ╰) ╮

효과에 따라 :

    길이 n 배열 p 모두 동결하기 시작하고
    모든 영구적 인 자료를 p k i P_ {K_ {난}}
    각 요청의 출시 후, L I S LIS

문제 해결 아이디어 :

그림 삽입 설명 여기
    찾으려면 x 엑스 L I S LIS , 트리 유지 보수의 배열을 고려
    펜윅 나무 t [ i ] t [i]를 각 지점에 기록 L I S LIS 위치보다는 값

코어 : 기대 L I S LIS , 펜윅 트리 유지 관리 위치

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
const int maxn = 4e5 + 5;
int T, n, a[maxn], k[maxn], ans[maxn];
int l[maxn], r[maxn], used[maxn];
int t[maxn], f[maxn], pre[maxn]; 

inline int lb(int x){
	return x & -x;
}

inline void update(int x, int p){
	for(int i=x; i<=n; i+=lb(i))
		if(f[t[i]] < f[p]) t[i] = p;
}

inline int query(int x){
	int ret = 0;
	for(int i=x; i; i-=lb(i))
		if(f[t[i]] > f[ret]) ret = t[i];
	return ret;
}

inline void lis(){
	for(int i=0; i<=n+1; i++) t[i] = f[i] = used[i] = 0;
	for(int i=r[0]; i<=n+1; i=r[i]){
		int q = query(a[i]);
		f[i] = f[q] + 1;
		pre[i] = q;
		update(a[i], i);
	}
	for(int i=n+1; i; i=pre[i]) used[i] = 1;
}

int main() {
	scanf("%d", &T);
	while(T--){
		scanf("%d", &n);
		a[n+1] = n + 1;
		for(int i=1; i<=n; i++) scanf("%d", a+i);
		for(int i=1; i<=n; i++) scanf("%d", k+i);
		for(int i=0; i<=n+1; i++) l[i] = i-1, r[i] = i+1;
		lis();
		for(int i=n; i; i--){
			ans[i] = f[n+1] - 1;
			l[r[k[i]]] = l[k[i]];
			r[l[k[i]]] = r[k[i]];
			if(used[k[i]]) lis();
		}
		for(int i=1; i<=n; i++) printf("%d%c", ans[i], i<n ? ' ' : '\n');
	}
}
게시 된 221 개 원래 기사 · 원 찬양 (220) ·은 20000 +를 볼

추천

출처blog.csdn.net/Scar_Halo/article/details/103012082