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

CodeVS-2573-黑匣子

时间:2017-05-13 13:25:05      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:blank   cpp   pac   刷题   targe   pre   主席树   splay   else   

看到题目感觉有点坏...

  区间第k大,插入某个数...看起来怎么那么像主席树...、

  tmd我不会

    然后看看分类....堆?花了30min乱打一波优先队列...突然想起来stl不能直接输出q[k]。。。

    然后转换思路...嗯,从树的角度出发...突然想起某道题...戳我

      这样就变成了模板提...不过对模板不熟...调了3h+才发现有个小错误>_<(蒟蒻就要多刷题...)

      于是就变成了一道送温暖提(Tjm:打波splay暖暖手)

  题目链接:http://codevs.cn/problem/2573/

  代码:
    

#include<bits/stdc++.h>
#define ll long long
#define maxn 60010
using namespace std;

int num[maxn],son[maxn][3],f[maxn],value[2000000],data[maxn];
int root,tot,n,m,a[maxn];

void rotate(int x,int w){
	int y=f[x];
	num[y]=num[y]-num[x]+num[son[x][w]];
	num[x]=num[x]-num[son[x][w]]+num[y];
	son[y][3-w]=son[x][w];
	if(son[x][w]) f[son[x][w]]=y;
	f[x]=f[y];
	if(f[y]){
		if(son[f[y]][1]==y) son[f[y]][1]=x;
		else son[f[y]][2]=x;
	}
	f[y]=x;son[x][w]=y;
}

void splay(int x){
	while(f[x]!=0){
		int y=f[x];
			if(f[y]==0){
				if(son[y][1]==x) rotate(x,2);
				else rotate(x,1);
			}
			else 
			if(son[f[y]][1]==y) 
				if(x==son[y][1]){
					rotate(y,2);rotate(x,2);
				}
				else{
					rotate(x,1);rotate(x,2);
				}
			else{
				if(x==son[y][2]){
					rotate(y,1);rotate(x,1); 
				}
				else{
					rotate(x,2);rotate(x,1);
				}		
			}
	}
	root=x;
}

int search(int x,int w){
	while(data[x]!=w){
		if(w==data[x]) return x;
			if(w<data[x]){
				if(son[x][1]==0) break;
				x=son[x][1];
			}
			else{
				if(son[x][2]==0) break;
				x=son[x][2];
			}
	}
	return x;
}

void insert(int w){
	bool flag;
	if(tot==0){
		tot=1;
		f[1]=0;num[1]=1;data[1]=w;root=1;value[1]=1;
		return;
	}
	int k=search(root,w);
	int kk;
	if(data[k]==w){
		value[k]++;kk=k;
		flag=1;
	} 
	else{
		tot++;data[tot]=w;f[tot]=k;value[tot]=1;num[tot]=1;
		if(data[k]>w)
			son[k][1]=tot;
		else son[k][2]=tot;
		flag=0;
	}
	while(k){
		num[k]++;
		k=f[k];
	}
	if(flag) splay(kk);else splay(tot);
}

int kth(int x,int w){
	int i=root;
	while(!((x>=num[son[i][w]]+1)&&(x<=num[son[i][w]]+value[i]))&&(i!=0)){
		if(x>num[son[i][w]]+value[i]){
			x=x-num[son[i][w]]-value[i];
			i=son[i][3-w];
		}
		else i=son[i][w];
	}
	int tmp=i;
	splay(i);
	return tmp;
}

int main(){
	int last=1;
	scanf("%d %d",&n,&m);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		for(int i=1;i<=m;i++){
			int x;
			scanf("%d",&x);
				for(int j=last;j<=x;j++) insert(a[j]);
			last=x+1;
			printf("%d\n",data[kth(i,1)]);
		}
}

  

CodeVS-2573-黑匣子

标签:blank   cpp   pac   刷题   targe   pre   主席树   splay   else   

原文地址:http://www.cnblogs.com/Jrzn/p/6848627.html

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