记录编号 318817 评测结果 AAAAAAAAAA
题目名称 2421.[HZOI 2016] 简单的Treap 最终得分 100
用户昵称 AntiLeaf 是否通过 通过
代码语言 C++ 运行时间 0.813 s
提交时间 2016-10-09 21:19:37 内存使用 8.38 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=530010,num[]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288};
namespace mine{
	template<class T>inline void readint(T &__x){
		static int __c;
		static bool __neg;
		__x=0;
		__neg=false;
		do __c=getchar();while(__c==' '||__c=='\n'||__c=='\r'||__c=='\t');
		if(__c=='-'){
			__neg=true;
			__c=getchar();
		}
		for(;__c>='0'&&__c<='9';__c=getchar())__x=__x*10+(__c^48);
		if(__neg)__x=-__x;
	}
	template<class T>inline void putint(T __x){
		static int __a[40],__i,__j;
		static bool __neg;
		__neg=__x<0;
		if(__neg)__x=-__x;
		__i=0;
		do{
			__a[__i++]=__x%(T)10^(T)48;
			__x/=10;
		}while(__x);
		if(__neg)putchar('-');
		for(__j=__i-1;__j^-1;__j--)putchar(__a[__j]);
	}
}
using namespace mine;
struct A{
	int a,p;
	inline bool operator<(const A &x)const{return a<x.a;}
}a[maxn];
void build(const int&,const int&);
void qmin(int,int,int&);
int n,m,id[maxn<<1];
int main(){
#define MINE
#ifdef MINE
	freopen("treap.in","r",stdin);
	freopen("treap.out","w",stdout);
#endif
	int __size__=128<<20;
	char *__p__=(char*)malloc(__size__)+__size__;
	__asm__("movl %0, %%esp\n"::"r"(__p__));
	readint(n);
	m=n;
	for(int i=1;i<=n;i++)readint(a[i].a);
	for(int i=1;i<=n;i++)readint(a[i].p);
	sort(a+1,a+n+1);
	//for(int i=1;i<=n;i++)printf("%d ",a[i].p);printf("\n");
	a[0].p=~(1<<31);
	n=*lower_bound(num,num+20,n+2);//printf("%d\n",n);getchar();getchar();
	for(int i=1;i<=m;i++)id[i+n]=i;
	for(int i=n-1;i;i--){
		if(a[id[i<<1]].p<a[id[i<<1|1]].p)id[i]=id[i<<1];
		else id[i]=id[i<<1|1];
	}
	//for(int i=1;i<n<<1;i++)printf("i=%d id=%d\n",i,id[i]);
	build(1,m);
#ifndef MINE
	printf("\n--------------------DONE--------------------\n");
	for(;;);
#endif
	return 0;
}
inline void build(const int &l,const int &r){
	if(l>r)return;
	//printf("build(%d,%d)\n",l,r);
	else if(l==r){
		putint(a[l].a);
		putchar(' ');
		return;
	}
	int rt;
	qmin(l+1,r+1,rt);
	//printf("rt=%d\n",rt);getchar();
	putint(a[rt].a);
	putchar(' ');
	build(l,rt-1);
	build(rt+1,r);
}
inline void qmin(int l,int r,int &ans){
	ans=0;
	//printf("qmin(%d,%d)\n",l,r);
	l+=n-2;
	r+=n;
	while(l^r^1){
		//printf("l=%d r=%d\n",l,r);
		if((~l&1)&&a[id[l^1]].p<a[ans].p)ans=id[l^1];
		if((r&1)&&a[id[r^1]].p<a[ans].p)ans=id[r^1];
		l>>=1;r>>=1;
	}
	//printf("return %d\n",ans);
}
/*
用zkw写RMQ...我就不信我卡不过NewBee了......
我们需要把整个区间向右平移一位,这样一个点对应的叶子就是(x+n-1)了。
*/