主席树 90 pts 求助
查看原帖
主席树 90 pts 求助
363036
chlchl楼主2022/10/27 21:54

rt,不知道为什么错了,也不知道为什么需要离散化。

#include<bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;
const int M = N << 5;
int n, m, a[N];
int tot, rt[N], ls[M], rs[M], lst[M];
//主席树,查询 [l,r] 时在第 r 棵树找最小的上一个出现在 l 以前的权值
//所以在主席树上进行二分

int update(int u, int l, int r, int p, int v){
	int o = ++tot;
	lst[o] = lst[u], ls[o] = ls[u], rs[o] = rs[u];
	if(l == r){
		lst[o] = v;
		return o;
	}
	int mid = (l + r) >> 1;
	if(p <= mid)
		ls[o] = update(ls[o], l, mid, p, v);
	else
		rs[o] = update(rs[o], mid + 1, r, p, v);
	lst[o] = min(lst[ls[o]], lst[rs[o]]);
	return o;
}

int query(int o, int l, int r, int v){
	if(l == r)
		return l;
	int mid = (l + r) >> 1;
	if(lst[ls[o]] < v)
		return query(ls[o], l, mid, v);
	else
		return query(rs[o], mid + 1, r, v);
}

int main(){
	scanf("%d%d", &n, &m);
	for(int i=1;i<=n;i++){
		scanf("%d", &a[i]), a[i]++;
		if(a[i] > n + 1)
			rt[i] = rt[i - 1];
		else
			rt[i] = update(rt[i - 1], 1, n, a[i], i);
	}
	while(m--){
		int l, r;
		scanf("%d%d", &l, &r);
		printf("%d\n", query(rt[r], 1, n, l) - 1);
	}
	return 0;
}
2022/10/27 21:54
加载中...