Chang'an(Black Box-线段树)




线段树



#include <bits/stdc++.h>

using namespace std;

struct rect{
	int l, r, c, x;
};
struct rec{
	int x, p, ans, rank;
};
rect tree[800004];
rec a[200004], get[20000];
bool cmpx(const rec &a, const rec &b){
	return a.x<b.x;
}
bool cmpp(const rec &a, const rec &b){
	return a.p<b.p;
}
void build(int i, int l, int r){
	tree[i].l = l;
	tree[i].r = r;
	tree[i].c = 0;
	if (l!=r) {
		build(2*i, l, (l+r)/2);
		build(2*i+1, (l+r)/2+1, r);
	} else{
		tree[i].x = a[r].x;
	}
}
void change(int i, int p){
	if (tree[i].l==tree[i].r){
		tree[i].c=1;
		return;
	}
	if (p<=tree[2*i].r) {change(2*i, p);} else {change(2*i+1, p);	}
	tree[i].c= tree[2*i].c + tree[2*i+1].c;
}
int find(int i, int x){
	if (tree[i].l==tree[i].r){
		return tree[i].x;
	}
	if (x<=tree[2*i].c) {return find(2*i, x);} else {return find(2*i+1, x-tree[2*i].c);}
}
int main(){
//	freopen("d.in", "r", stdin);
	int T, l, n, m;
	cin>>T;
	for(int I=1; I<=T; I++){
		cout<<"Case #"<<I<<":"<<endl;
		cin>>n>>m;
		for(int i=1; i<=n; i++){
			cin>>a[i].x;
			a[i].p=i;
		}
		for(int i=1; i<=m; i++){
			cin>>get[i].x;
			get[i].p=i;
		}
		sort(a+1, a+1+n, cmpx);
		for(int i=1; i<=n; i++){
			a[i].ans = i;
		}
		build(1, 1, n);
		sort(a+1, a+1+n, cmpp);
		sort(get+1, get+1+m, cmpx);
		l = 1;
		get[m+1].x=-1;
		for(int i=1; i<=n; i++){
//			cout<<a[i].ans<<endl;
			change(1, a[i].ans);
			while(i==get[l].x) {
				get[l].ans=find(1, l);
				l++;
			}
		}
		sort(get+1, get+1+m, cmpp);
		for(int i=1; i<=m; i++){
			cout<<get[i].ans<<endl;
		}
	}
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值