[HNOI2002]营业额统计 Splay tree
2013-07-14 21:27
295 查看
Splay tree入门题,学好代码风格,学习HH大牛的,传送门。。
#include <functional> #include <algorithm> #include <iostream> //#include <ext/rope> #include <fstream> #include <sstream> #include <iomanip> #include <numeric> #include <cstring> #include <cassert> #include <cstdio> #include <string> #include <vector> #include <bitset> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <list> #include <set> #include <map> using namespace std; //using namespace __gnu_cxx; //define #define pii pair<int,int> #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define PI acos(-1.0) //typedef typedef long long LL; typedef unsigned long long ULL; //const const int N=100005; const int INF=0x3f3f3f3f; const int MOD=100000,STA=8000010; const LL LNF=1LL<<60; const double EPS=1e-8; const double OO=1e15; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //Daily Use ... inline int sign(double x){return (x>EPS)-(x<-EPS);} template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;} template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;} template<class T> inline T lcm(T a,T b,T d){return a/d*b;} template<class T> inline T Min(T a,T b){return a<b?a:b;} template<class T> inline T Max(T a,T b){return a>b?a:b;} template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);} template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);} template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));} template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));} //End int pre ,key ,ch [2],root,tot; //分别表示父结点,键值,左右孩子(0为左孩子,1为右孩子),根结点,结点数量 int n; //新建一个结点 void addn(int &r,int fa,int k) { r=++tot; pre[r]=fa; key[r]=k; ch[r][0]=ch[r][1]=0; //左右孩子为空 } //旋转,kind为1为右旋,kind为0为左旋 int Rotate(int x,int kind) { int y=pre[x],z=pre[y]; //类似SBT,要把其中一个分支先给父节点 ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; //如果父节点不是根结点,则要和父节点的父节点连接起来 if(z)ch[z][ch[z][1]==y]=x; pre[x]=z; ch[x][kind]=y; pre[y]=x; } //Splay调整,将根为r的子树调整为goal int Splay(int r,int goal) { int y,kind; while(pre[r]!=goal){ //父节点即是目标位置,goal为0表示,父节点就是根结点 y=pre[r]; if(pre[y]==goal){ Rotate(r,ch[y][0]==r); } else { kind=ch[pre[y]][0]==y; //两个方向不同,则先左旋再右旋 if(ch[y][kind]==r){ Rotate(r,!kind); Rotate(r,kind); } //两个方向相同,相同方向连续两次 else { Rotate(y,kind); Rotate(r,kind); } } } //更新根结点 if(goal==0)root=r; } int Insert(int k) { int r=root; while(ch[r][k>key[r]]){ //不重复插入 if(key[r]==k){ Splay(r,0); return 0; } r=ch[r][k>key[r]]; } addn(ch[r][k>key[r]],r,k); //将新插入的结点更新至根结点 Splay(ch[r][k>key[r]],0); return 1; } //找前驱,即左子树的最右结点 int getpre(int x) { if(!ch[x][0])return -INF; x=ch[x][0]; while(ch[x][1])x=ch[x][1]; return key[x]; } //找后继,即右子树的最左结点 int getsuf(int x) { if(!ch[x][1])return INF; x=ch[x][1]; while(ch[x][0])x=ch[x][0]; return key[x]; } int main() { // freopen("in.txt","r",stdin); int i,a,ans; while(~scanf("%d",&n)) { ans=root=tot=0; for(i=0;i<n;i++){ if(scanf("%d",&a)==EOF)a=0; if(i==0){ ans+=a; addn(root,0,a); } else { if(Insert(a)==0)continue; ans+=Min(a-getpre(root),getsuf(root)-a); } } printf("%d\n",ans); } return 0; }
相关文章推荐
- [HNOI2002]营业额统计 Splay tree
- [HNOI2002]营业额统计 Splay tree入门题
- bzoj 1588 [HNOI2002]营业额统计 splay tree
- 1588: [HNOI2002]营业额统计 (splay tree)
- [HNOI2002]营业额统计 Splay tree
- splay tree-hnoi2002 营业额统计
- BZOJ 题目1588: [HNOI2002]营业额统计(Splay Tree 求前驱后继)
- [HNOI2002]营业额统计(Splay tree 入门)
- BZOJ 1588 [HNOI2002]营业额统计(双向链表)
- BZOJ1588: [HNOI2002]营业额统计[BST]
- bzoj 1588 [HNOI2002]营业额统计 splay
- [HNOI2002]营业额统计 二叉搜索树的简单入门 splay
- 洛谷P2234 [HNOI2002]营业额统计(BZOJ1588)
- CJOJ 1308 【HNOI 2002 】营业额统计 / CodeVS 1296 营业额统计(STL,二分)
- BZOJ[1588][HNOI2002]营业额统计 Treap
- bzoj 1588 [HNOI2002] 营业额统计
- [HNOI2002]营业额统计
- bzoj1588 [HNOI2002]营业额统计 (treap)
- bzoj1588: [HNOI2002]营业额统计(权值线段树)
- BZOJ 1588: [HNOI2002] 营业额统计