1503: [NOI2004]郁闷的出纳员
2012-03-04 00:28
218 查看
1503: [NOI2004]郁闷的出纳员
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 2056 Solved: 711
[Submit][Status][Discuss]
Description
OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。 工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。 老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。 好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?Input
View Code/************************************************************** Problem: 1503 User: 314911229 Language: C++ Result: Accepted Time:972 ms Memory:6352 kb ****************************************************************/ /************************************************************** Problem: 1503 User: 314911229 Language: C++ Result: Accepted Time:2536 ms Memory:5956 kb 上个程序的 ****************************************************************/ //没有删除很多没有用的函数,所以代码很长 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> typedef struct node { node *lchild, *rchild, *pf;//左孩子,右孩子 int v, pri, size;//值和优先值 }*Node; int Minx, ans = 0; void update( Node &q ) { if( q->rchild && q->lchild ) q->size = q->rchild->size + q->lchild->size + 1; else if( q->rchild ) q->size = q->rchild->size + 1; else if( q->lchild ) q->size = q->lchild->size + 1; else q->size = 1; } //左旋转,返回新节点 Node Left_Rotate(Node &q) { Node p = q->rchild; q->rchild = p->lchild; if( p->lchild ) p->lchild->pf = q; p->lchild = q; p->pf = q->pf; q->pf = p; update( q ); update( p ); return p; } //右旋转 Node Right_Rotate(Node &q) { Node p = q->lchild; //新节点为q左孩子 q->lchild = p->rchild; //p的右孩子给q的左孩子 if( p->rchild ) p->rchild->pf = q; p->rchild = q;// q成为p的右孩子 p->pf = q->pf; q->pf = p; update(q); update(p); return p; } Node NewNode(int t) { Node q = new node; q->lchild = NULL; q->rchild = NULL; q->v = t; q->size = 1; q->pri = rand( ); return q; } Node insert( Node &p, Node &q, Node father) { if( p == NULL ) { p = q; p->pf = father; } else if( p->v > q->v ) { p->lchild = insert(p->lchild, q, p); if(p->lchild->pri < p->pri ) p = Right_Rotate(p); } else { p->rchild = insert(p->rchild, q, p); if( p->rchild->pri < p->pri ) p = Left_Rotate(p); } update(p); return p; } Node find(Node p, int x) { if( p == NULL ) return NULL; if( p->v == x ) return p; else if( p->v > x ) return find(p->lchild, x); else return find(p->rchild, x); } //找出第k小的元素 Node OS_select(Node p, int k) { int num = 1; if( p == NULL ) return NULL; if( p->lchild ) num = p->lchild->size + 1; if( num == k ) return p; if( k > num ) return OS_select(p->rchild,k - num ); else return OS_select(p->lchild, k); } //确定一个元素(q->v)的秩 int OS_rank(Node p, Node q) { int num = 1; Node father = q; if( q->lchild ) num = q->lchild->size + 1; while( father != p ) { q = father; father = father->pf; if(father->rchild == q ) { if( father->lchild == NULL ) num += 1; else num += father->lchild->size + 1 ; } } return num; } Node del(Node &p, int x) { if( p ) { if( p->v > x ) { p->lchild = del(p->lchild, x); update( p ); } else if( p->v < x ) { p->rchild = del(p->rchild, x); update( p ); } else { if( p->rchild == NULL && p->lchild == NULL ) { delete p; return NULL; } else { if( p->lchild )//如果左孩子存在 { if( p->rchild == NULL || (p->lchild->pri < p->rchild->pri ))//右孩子为空,或左孩子小于右孩子 { p = Right_Rotate( p ); p->rchild = del(p->rchild, x); update( p ); } else //左孩子大于右孩子 { p = Left_Rotate( p ); p->lchild = del(p->lchild, x); update( p ); } } else //如果左孩子不存在 { p = Left_Rotate( p ); p->lchild = del(p->lchild, x); update( p ); } } } } return p; } //求最小值 Node Get_Min( Node p) { Node q = p; while( p ) { q = p; p = p->lchild; } return q; } //求最大值 Node Get_Max( Node p ) { Node q = p; while( p ) { q = p; p = p->rchild; } return q; } //求前驱 Node Get_Prev(Node p) { Node q = p->pf; if( p->lchild ) return Get_Max(p->lchild); while( q != NULL && p == q->lchild) { p = q; q = q->pf; } return q; } //求后继 Node Get_Next(Node p) { Node q = p->pf; if( p->rchild ) return Get_Min(p->rchild); while( q != NULL && p == q->rchild ) { p = q; q = q->pf; } return q; } Node sudel(Node &p) { if( p ) { if( p->v + ans < Minx ) { p = sudel(p->rchild); if( p ) update(p); } else { p->lchild = sudel(p->lchild); if( p->lchild ) update(p->lchild); } } if( p ) update(p); return p; } void preordertravel( Node p ) { if( p ) { preordertravel(p->lchild); if( p->pf ) printf("%d 节点个数%d 它得父亲节点为%d\n", p->v, p->size, p->pf->v); else printf("%d 节点个数%d 它得父亲节点为空\n", p->v, p->size); preordertravel(p->rchild); } } int main( ) { int N, pe, l, t; char str[100]; //srand(time(NULL)); while( scanf("%d%d",&N,&Minx) != EOF ) { Node root = NULL; pe = 0; l = 0; ans= 0; for( int i = 1; i <= N; i++) { scanf("%s%d",str, &t); Node q = NewNode(t-ans); if( str[0] == 'I' ) { if( t >= Minx ) root = insert(root, q,NULL), pe++; } else if(str[0] == 'S' ) { ans += -t; root = sudel(root); if( root ) { l += pe - root->size; pe = root->size; } else l += pe, pe = 0; // printf("l = %d pe = %d\n", l, pe); } else if(str[0] == 'A' ) ans += t; else if( str[0] == 'F' ) { Node p2 = OS_select(root,pe - t + 1); if( p2 ) printf("%d\n",p2->v + ans); else puts("-1"); } } printf("%d\n",l); } return 0; }
相关文章推荐
- 【splay】【树状数组】 BZOJ 1503 [NOI2004]郁闷的出纳员
- 1503: [NOI2004]郁闷的出纳员
- BZOJ1503: [NOI2004]郁闷的出纳员
- bzoj 1503 [NOI2004]郁闷的出纳员 splay
- BZOJ 1503 [NOI2004] 郁闷的出纳员 treap
- [BZOJ 1503] [NOI2004] 郁闷的出纳员
- bzoj1503【NOI2004】郁闷的出纳员
- BZOJ1503 [NOI2004]郁闷的出纳员
- bzoj 1503: [NOI2004]郁闷的出纳员 splay
- BZOJ 1503: [NOI2004]郁闷的出纳员 splay
- 【BZOJ 1503】[NOI2004]郁闷的出纳员 treap
- bzoj 1503 [NOI2004]郁闷的出纳员 splay tree
- (WA)BZOJ 1503: [NOI2004]郁闷的出纳员
- bzoj 1503: [NOI2004]郁闷的出纳员 Treap
- bzoj 1503: [NOI2004]郁闷的出纳员
- Bzoj1503 [NOI2004]郁闷的出纳员
- BZOJ 1503: [NOI2004]郁闷的出纳员
- 【BZOJ】1503: [NOI2004]郁闷的出纳员(Splay)
- bzoj1503[NOI2004]郁闷的出纳员 treap
- BZOJ1503【NOI2004】郁闷的出纳员