hdu4585splay
来源:互联网 发布:广数928螺纹编程格式 编辑:程序博客网 时间:2024/06/09 22:18
http://acm.hdu.edu.cn/showproblem.php?pid=4585
题意 开始有一个大和尚编号为1 攻击力1000 000 000 后来不断加入和尚 给出编号和攻击力 每加入一个和与他攻击力最接近的和尚比武,如果有两个差值一样 一大一小 就和小的比武 分别输出编号
数据量很大 使用treap树 简化每次查询的时间 缩短查询时树的深度
网上的treap模板
http://blog.csdn.net/clove_unique/article/details/50630280
这上面讲的挺详细
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;const int inf=0x3f3f3f3f;const int maxn=100010;class Treap{ public:struct Treap_Node{ Treap_Node *left,*right; int value,fix,weight,size;//fix为修正值,是随机产生的,保证二叉树不会退化的重要环节,weight为权值,size为子树大小}*root,*null;Treap(){ null=new struct Treap_Node; null->size=0; null->weight=0; null->value=inf; null->left=null; null->right=null; null->fix=inf; root=null;}void Treap_Print(Treap_Node *P){//从小到大输出 if(P!=null){ Treap_Print(P->left); printf("%d\n",P->value); Treap_Print(P->right); }}void Treap_Left_Rotate(Treap_Node *&a){//左旋之后仍不改变二叉树性质 Treap_Node *b=a->right; a->right=b->left; b->left=a; b->size=a->size; a->size=a->left->size+a->right->size+a->weight; a=b;}void Treap_Right_Rotate(Treap_Node *&a){//右旋之后仍不改变二叉树性质 Treap_Node *b=a->left; a->left=b->right; b->right=a; b->size=a->size; a->size=a->left->size+a->right->size+a->weight; a=b;}int Treap_Find(Treap_Node *P,int value){//查找有没有value这个数 if(P==null) return 0; if(P->value==value) return 1; else if(value<P->value) return Treap_Find(P->left,value); else return Treap_Find(P->right,value);}void Treap_Insert(Treap_Node *&P,int value){//插入一个数 if(P==null){ P=new Treap_Node; P->left=P->right=null;//左右儿子均为空 P->value=value; P->fix=rand(); P->weight=1; P->size=1; }else if(value==P->value){ P->weight++; } else if(value<P->value){ Treap_Insert(P->left,value); if(P->left->fix<P->fix) Treap_Right_Rotate(P); }else{ Treap_Insert(P->right,value); if(P->right->fix<P->fix) Treap_Left_Rotate(P); } P->size=P->left->size+P->right->size+P->weight;}void Treap_Delete(Treap_Node *&P,int value){//删除一个数 if(P==null) return ; if(value<P->value) Treap_Delete(P->left,value); else if(value>P->value) Treap_Delete(P->right,value); else if(P->weight>1) P->weight--; else if((P->left==NULL)&&(P->right==NULL)){ delete P; P=NULL; }else{ if(P->left->fix<P->right->fix) Treap_Left_Rotate(P); else Treap_Right_Rotate(P); Treap_Delete(P,value); } P->size=P->left->size+P->right->size+P->weight;}int Treap_pred(Treap_Node *P,int value,Treap_Node *optimal){ if(P==null||value==P->value) return optimal->value; if(P->value<value) return Treap_pred(P->right,value,P); else return Treap_pred(P->left,value,optimal);}int Treap_succ(Treap_Node *P,int value,Treap_Node *optimal){ if(P==null||value==P->value) return optimal->value; if(P->value>value) return Treap_succ(P->left,value,P); else return Treap_succ(P->right,value,optimal);}int Treap_Findkth(Treap_Node *P,int k){//求第K大的数 if(P==null) return 0; int t=P->left->size; if(k<t+1) return Treap_Findkth(P->left,k); else if(k>t+P->weight) return Treap_Findkth(P->right,k-(t+P->weight)); else return P->value;}int Treap_Rank(Treap_Node *P,int value,int cur){ int t=P->left->size; if(value==P->value) return t+cur+1; else if(value<P->value) return Treap_Rank(P->left,value,cur); else return Treap_Rank(P->right,value,t+cur+P->weight);}void Treap_erase(Treap_Node *&P) { if(P->left!=null) Treap_erase(P->left); if(P->right!=null) Treap_erase(P->right); delete P;}};int id[5000010];int main(){ int n,a,b; while(scanf("%d",&n)!=-1){ if(n==0) break; Treap tree; int ans1,ans2; memset(id,0,sizeof(id)); scanf("%d%d",&a,&b); printf("%d 1\n",a); id[b]=a;tree.Treap_Insert(tree.root,b); for(int i=1;i<n;i++){ scanf("%d%d",&a,&b); id[b]=a; tree.Treap_Insert(tree.root,b); int ans; int k=tree.Treap_Rank(tree.root,b,0); ans1=tree.Treap_Findkth(tree.root,k-1); ans2=tree.Treap_Findkth(tree.root,k+1); if(!ans1) ans=ans2; else if(!ans2) ans=ans1; else{ if(b-ans1<=ans2-b){ ans=ans1; }else ans=ans2; } printf("%d %d\n",a,id[ans]); } } return 0;}
#include<iostream>#include<cstdio>#include<cstdlib>using namespace std;struct data{ int l,r,v,size,rnd,w;}tr[100005];int n,size,root,ans;void update(int k)//更新结点信息{ tr[k].size=tr[tr[k].l].size+tr[tr[k].r].size+tr[k].w;}void rturn(int &k){ int t=tr[k].l;tr[k].l=tr[t].r;tr[t].r=k; tr[t].size=tr[k].size;update(k);k=t;}void lturn(int &k){ int t=tr[k].r;tr[k].r=tr[t].l;tr[t].l=k; tr[t].size=tr[k].size;update(k);k=t;}void insert(int &k,int x){ if(k==0) { size++;k=size; tr[k].size=tr[k].w=1;tr[k].v=x;tr[k].rnd=rand(); return; } tr[k].size++; if(tr[k].v==x)tr[k].w++; else if(x>tr[k].v) { insert(tr[k].r,x); if(tr[tr[k].r].rnd<tr[k].rnd)lturn(k); } else { insert(tr[k].l,x); if(tr[tr[k].l].rnd<tr[k].rnd)rturn(k); } }void del(int &k,int x){ if(k==0)return; if(tr[k].v==x) { if(tr[k].w>1) { tr[k].w--;tr[k].size--;return; } if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r; else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd) rturn(k),del(k,x); else lturn(k),del(k,x); } else if(x>tr[k].v) tr[k].size--,del(tr[k].r,x); else tr[k].size--,del(tr[k].l,x);}int query_rank(int k,int x){ if(k==0)return 0; if(tr[k].v==x)return tr[tr[k].l].size+1; else if(x>tr[k].v) return tr[tr[k].l].size+tr[k].w+query_rank(tr[k].r,x); else return query_rank(tr[k].l,x);}int query_num(int k,int x){ if(k==0)return 0; if(x<=tr[tr[k].l].size) return query_num(tr[k].l,x); else if(x>tr[tr[k].l].size+tr[k].w) return query_num(tr[k].r,x-tr[tr[k].l].size-tr[k].w); else return tr[k].v;}void query_pro(int k,int x){ if(k==0)return; if(tr[k].v<x) { ans=k;query_pro(tr[k].r,x); } else query_pro(tr[k].l,x);}void query_sub(int k,int x){ if(k==0)return; if(tr[k].v>x) { ans=k;query_sub(tr[k].l,x); } else query_sub(tr[k].r,x);}int main(){ scanf("%d",&n); int opt,x; for(int i=1;i<=n;i++) { scanf("%d%d",&opt,&x); switch(opt) { case 1:insert(root,x);break; case 2:del(root,x);break; case 3:printf("%d\n",query_rank(root,x));break; case 4:printf("%d\n",query_num(root,x));break; case 5:ans=0;query_pro(root,x);printf("%d\n",tr[ans].v);break; case 6:ans=0;query_sub(root,x);printf("%d\n",tr[ans].v);break; } } return 0;}
0 0
- hdu4585splay
- 游戏底层逻辑,运动&&寻路(一)
- 匿名存储过程块学习
- leetcode刷题,总结,记录,备忘114
- POJ 1730 Perfect Pth Powers(素数筛选法)
- Java中&&和&以及||和|的区别
- hdu4585splay
- 4种进程间通信方式详解
- JS页面跳转(转载)
- Android自定义View或ViewGroup的流程
- Android开发文档翻译之——Bound Services
- Visual Studio 2015 使用时的一些错误
- everything is object
- 【POJ 1765】 November Rain(离散化+扫描线)
- SpringMVC介绍之Validation