Vijos1507 [NOI2004] 郁闷的出纳员
Orz黄学长……不过觉得黄学长的代码将值相同的元素开成多个点有点不科学所以自己改一改,将值相同的元素放在一个节点里记录次数。
交了三次黄学长代码平均2306ms,自己的三次平均1209ms。
2015.11.19 update: 数据不是随机生成的吗……值相同的元素会那么多?
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <ctime> 6 #define rep(i,l,r) for(int i=l; i<=r; i++) 7 #define clr(x,y) memset(x,y,sizeof(x)) 8 using namespace std; 9 typedef long long ll; 10 const int INF = 0x3f3f3f3f; 11 const int maxn = 100010; 12 struct node{ 13 int l,r,v,w,size,rnd; 14 }t[maxn]; 15 int n,low,x,root,cnt=0,tot=0,delta=0; char ch; 16 inline int read(){ 17 int ans = 0, f = 1; 18 char c = getchar(); 19 while (!isdigit(c)){ 20 if (c == '-') f = -1; 21 c = getchar(); 22 } 23 while (isdigit(c)){ 24 ans = ans * 10 + c - '0'; 25 c = getchar(); 26 } 27 return ans * f; 28 } 29 void update(int w){ 30 t[w].size = t[t[w].l].size + t[t[w].r].size + t[w].w; 31 } 32 void rotl(int &w){ 33 int k = t[w].r; t[w].r = t[k].l; t[k].l = w; 34 update(w); update(k); w = k; 35 } 36 void rotr(int &w){ 37 int k = t[w].l; t[w].l = t[k].r; t[k].r = w; 38 update(w); update(k); w = k; 39 } 40 void insert(int x,int &w){ 41 if (!w){ 42 w = ++tot; t[w].v = x; t[w].w = t[w].size = 1; 43 t[w].rnd = rand(); 44 return; 45 } 46 t[w].size++; if (t[w].v == x) t[w].w++; 47 else if (x < t[w].v){ 48 insert(x,t[w].l); 49 if (t[t[w].l].rnd < t[w].rnd) rotr(w); 50 } 51 else{ 52 insert(x,t[w].r); 53 if (t[t[w].r].rnd < t[w].rnd) rotl(w); 54 } 55 } 56 int leave(int x,int &w){ 57 int ret; 58 if (!w) return 0; 59 if (t[w].v < x){ 60 ret = t[t[w].l].size + t[w].w; w = t[w].r; 61 ret += leave(x,w); 62 } 63 else{ 64 ret = leave(x,t[w].l); 65 t[w].size -= ret; 66 } 67 return ret; 68 } 69 int query(int x,int w){ 70 if (!w) return 0; 71 if (x <= t[t[w].l].size) return query(x,t[w].l); 72 else if (x > t[t[w].l].size + t[w].w) return query(x-t[w].w-t[t[w].l].size,t[w].r); 73 else return t[w].v + delta; 74 } 75 int main(){ 76 srand(time(0)); 77 n = read(); low = read(); 78 rep(i,1,n){ 79 scanf("%c",&ch); x = read(); 80 switch(ch){ 81 case 'I': if (x >= low) insert(x-delta,root); break; 82 case 'A': delta += x; break; 83 case 'S': delta -= x; cnt += leave(low-delta,root); break; 84 case 'F': 85 if (t[root].size < x) printf("-1\n"); 86 else printf("%d\n",query(t[root].size-x+1,root)); 87 break; 88 } 89 } 90 printf("%d\n",cnt); 91 return 0; 92 }