hdu 5349 维护序列 OR Treap

由于只删除最小值和只查询最大值,所以我们只要维护一个maxn和一个size即可,需要注意的是删除到集合空时需要重新将maxn赋值为无穷小。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5
 6 int main ()
 7 {
 8     int n;
 9     while ( scanf("%d", &n) != EOF )
10     {
11         int op, tmp, maxn = -1111111111, size = 0;
12         for ( int i = 0; i < n; i++ )
13         {
14             scanf("%d", &op);
15             if ( op == 1 )
16             {
17                 scanf("%d", &tmp);
18                 size++;
19                 if ( tmp > maxn ) maxn = tmp;
20             }
21             else if ( op == 2 )
22             {
23                 if ( size > 0 )
24                 {
25                     size--;
26                     if ( size == 0 ) maxn = -1111111111;
27                 }
28             }
29             else
30             {
31                 if ( size == 0 )
32                 {
33                     printf("0\n");
34                 }
35                 else
36                 {
37                     printf("%d\n", maxn);
38                 }
39             }
40         }
41     }
42     return 0;
43 }

另外,别的平衡的数据结构也可以过,这里用的是Treap(主要是测模板),比赛推荐用multiset。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cstdio>
  5 using namespace std;
  6
  7 struct Node
  8 {
  9     Node * ch[2];
 10     int v, r, size;
 11     int cmp( int x )
 12     {
 13         if ( x == v ) return -1;
 14         return x < v ? 0 : 1;
 15     }
 16     void maintain()
 17     {
 18         size = 1;
 19         if ( ch[0] != NULL ) size += ch[0]->size;
 20         if ( ch[1] != NULL ) size += ch[1]->size;
 21     }
 22 };
 23
 24 Node * root;
 25
 26 void rotate( Node * & o, int d )
 27 {
 28     Node * k = o->ch[d ^ 1];
 29     o->ch[d ^ 1] = k->ch[d];
 30     k->ch[d] = o;
 31     o->maintain();
 32     k->maintain();
 33     o = k;
 34 }
 35
 36 void insert( Node * & o, int x )
 37 {
 38     if ( o == NULL )
 39     {
 40         o = new Node();
 41         o->ch[0] = o->ch[1] = NULL;
 42         o->v = x;
 43         o->r = rand();
 44         o->size = 1;
 45     }
 46     else
 47     {
 48         int d = ( x <= o->v ? 0 : 1 );
 49         insert( o->ch[d], x );
 50         if ( o->ch[d]->r > o->r )
 51         {
 52             rotate( o, d ^ 1 );
 53         }
 54         else
 55         {
 56             o->maintain();
 57         }
 58     }
 59 }
 60
 61 void remove( Node * & o, int x )
 62 {
 63     int d = o->cmp(x);
 64     if ( d == -1 )
 65     {
 66         if ( o->ch[0] != NULL && o->ch[1] != NULL )
 67         {
 68             int dd = ( o->ch[0]->r > o->ch[1]->r ? 1 : 0 );
 69             rotate( o, dd );
 70             remove( o->ch[dd], x );
 71         }
 72         else
 73         {
 74             Node * u = o;
 75             if ( o->ch[0] == NULL ) o = o->ch[1];
 76             else o = o->ch[0];
 77             delete u;
 78         }
 79     }
 80     else
 81     {
 82         remove( o->ch[d], x );
 83     }
 84     if ( o != NULL ) o->maintain();
 85 }
 86
 87 int findm( Node * o, int d )
 88 {
 89     while ( o->ch[d] != NULL ) o = o->ch[d];
 90     return o->v;
 91 }
 92
 93 int main ()
 94 {
 95     int n;
 96     while ( scanf("%d", &n) != EOF )
 97     {
 98         root = NULL;
 99         for ( int i = 0; i < n; i++ )
100         {
101             int op, x;
102             scanf("%d", &op);
103             if ( op == 1 )
104             {
105                 scanf("%d", &x);
106                 insert( root, x );
107             }
108             else if ( op == 2 )
109             {
110                 if ( root != NULL )
111                 {
112                     x = findm( root, 0 );
113                     remove( root, x );
114                 }
115             }
116             else
117             {
118                 if ( root == NULL )
119                 {
120                     x = 0;
121                 }
122                 else
123                 {
124                     x = findm( root, 1 );
125                 }
126                 printf("%d\n", x);
127             }
128         }
129     }
130     return 0;
131 }
时间: 2024-10-29 03:47:48

hdu 5349 维护序列 OR Treap的相关文章

【multiset】hdu 5349 MZL&#39;s simple problem

[multiset]hdu 5349 MZL's simple problem 题目链接:hdu 5349 MZL's simple problem 题目大意 n次操作,插入元素.删除最小元素.查询最大元素并输出. C++STL的multiset的使用 set--多元集合(元素不可重复),multiset--可重复元素的多元集合 多元集合(MultiSets)和集合(Sets)相像,只不过支持重复对象.(具体用法请参照set容器) set和multiset内部是以平衡二叉树实现的: 从内部数据结

1798: [Ahoi2009]Seq 维护序列seq

1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5886  Solved: 2087[Submit][Status][Discuss] Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和

hdu 5349 MZL&#39;s simple problem

Problem Description A simple problem Problem Description You have a multiple set,and now there are three kinds of operations: 1 x : add number x to set 2 : delete the minimum number (if the set is empty now,then ignore it) 3 : query the maximum numbe

bzoj1798[Ahoi2009]Seq 维护序列seq

bzoj1798[Ahoi2009]Seq 维护序列seq 题意: 维护序列,支持区间加.区间乘.区间求和模一个数.序列大小和操作数≤100000 题解: 线段树,加标记和乘标记的处理同bzoj4003.模的时候注意细节. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define m

hdu 5349 MZL&#39;s simple problem(multiset)

代码: #include<set> #include<cstdio> using namespace std; multiset<int> st; int main() { int n; multiset<int>::iterator it; while(scanf("%d",&n)==1) { st.clear(); int k,num; for(int i=0; i<n; i++) { scanf("%d&qu

bzoj1798: [Ahoi2009]Seq 维护序列seq 2011-12-20

1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MB Submit: 497  Solved: 203 [Submit][Status][Discuss] Description 老 师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的

BZOJ1798题解 Seq维护序列题解 双tag裸线段树

BZOJ1798题解 Seq维护序列题解 双tag裸线段树 1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5549  Solved: 1951[Submit][Status][Discuss] Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)

hdu - 5349 MZL&#39;s simple problem(解题报告)

A - MZL's simple problem Time Limit:1500MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description A simple problem Problem Description You have a multiple set,and now there are three kinds of operations: 1 x : add number

bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=1798 Description 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列