码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 1028D: Order book

时间:2018-08-29 21:27:11      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:==   scanf   order   插入   最小值   name   说明   for   tchar   

模拟。

考虑每次交易必须选择buy的最大值和sell的最小值

维护一个有序集合$S$,每次ACCEPT操作都会确定剩下的buy集合和sell集合

也就是说,sell的是有序集合的右侧,buy是有序集合的左侧。

我们一直维护sell的最小值$A$和buy的最大值$B$。

对于ACCEPT操作,如果新的元素是在$A$和$B$之间,是合法的

如果既不是$A$,也不是$B$,那么说明这两个sell和buy可以随意选,将答案乘2

再重新确定$A$和$B$的值。

对于ADD操作,我们将其插入有序集合,如果该数小于$B$,大于$A$。

那么这个数目前可以随意的选择(如果重新确定了$A$和$B$就不行了)

最后就是累计的答案乘上可以随意选择的数+1,就是枚举从哪里分开,左边是buy,右边是sell

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define MOD 1000000007
 4 inline int read() {
 5     char ch = getchar(); int x = 0, f = 1;
 6     while(ch < 0 || ch > 9) {
 7         if(ch == -) f = -1;
 8         ch = getchar();
 9     }
10     while(0 <= ch && ch <= 9) {
11         x = x * 10 + ch - 0;
12         ch = getchar();
13     }
14     return x * f;
15 }
16 char s[20];
17 set<int> S;
18 int mx, mn;
19 int main() {
20     int T = read();
21     S.insert(-1e9);
22     S.insert(1e9);
23     mx = 1e9;
24     mn = -1e9;
25     int wt = 1;
26     int Ans = 1;
27     while(T --) {
28         scanf("%s", s);
29         int x = read();
30         if(s[1] == D) {
31             S.insert(x);
32             if(mn < x && x < mx) ++ wt;
33         }
34         else {
35             if(x < mn || x > mx) {
36                 return puts("0"), 0;
37             }
38             if(x != mn && x != mx) {
39                 Ans = Ans * 2 % MOD;
40             } 
41             wt = 1;
42             S.erase(x);
43             set<int> :: iterator it = S.lower_bound(x);
44             mx = *it;
45             mn = *(-- it);
46         }
47     }
48     printf("%d\n", 1ll * Ans * wt % MOD);
49 }

 

codeforces 1028D: Order book

标签:==   scanf   order   插入   最小值   name   说明   for   tchar   

原文地址:https://www.cnblogs.com/iamqzh233/p/9556682.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!