码迷,mamicode.com
首页 > 其他好文 > 详细

Chang'an(Black Box-线段树)

时间:2015-04-24 21:14:31      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

技术分享


线段树



#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;
}





Chang'an(Black Box-线段树)

标签:

原文地址:http://blog.csdn.net/nike0good/article/details/45250455

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!