标签:
平衡树的题,Treap破之,比较难搞的出现相同题数罚时的情况,解决方法是在每个结点用一个set,比较值的时候可以把题数和罚时保存到一起。
初始化有一定技巧。细节很多容易出错。
写错一个变量名字查好久,尴尬
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> using namespace std; #define PB push_back #define MP make_pair #define fi first #define se second #define cer(x) cout<<#x<<‘=‘<<endl typedef long long ll; const int maxn = 1e4+5, MAXPEN = 1e6;//60*20+3000+666; int st[maxn], val[maxn], pen[maxn][10],lst[maxn],lsa[maxn]; struct CMP { bool operator()(int a,int b) const{ return lsa[a] < lsa[b]; } }; struct Node { int ch[2],r,s,v; set<int,CMP> vs; }nds[maxn*2]; queue<int> fre; inline int newNode(int x) { int i; Node &u = nds[i = fre.front()]; fre.pop(); u.ch[0] = u.ch[1] = 0; u.r = rand(); u.s = 1; u.v = val[x]; u.vs.clear(); u.vs.insert(x); return i; } inline void delt(int x) { fre.push(x); } inline int cmp(int a,int b) { if(a == b) return -1; return a>b? 0:1; } inline void mt(int i) { Node&u = nds[i]; u.s = (int)u.vs.size() + nds[u.ch[0]].s + nds[u.ch[1]].s; } inline void rot(int &o,int d) { int k = nds[o].ch[d^1]; nds[o].ch[d^1] = nds[k].ch[d]; nds[k].ch[d] = o; mt(o); mt(k); o = k; } inline void initTreap(int n) { for(int i = 1; i < n; i++) fre.push(i); nds[0].s = 0; } void inst(int &o,int x) { if(!o) { o = newNode(x); return; } Node &u = nds[o]; int d = cmp(u.v,val[x]); if(~d){ inst(u.ch[d],x); if(u.r < nds[u.ch[d]].r) rot(o,d^1); //else }else { u.s++; u.vs.insert(x); } mt(o); } void rmov(int &o,int x) { Node &u = nds[o]; int d = cmp(u.v,val[x]); if(~d){ rmov(u.ch[d],x); }else { if((int)u.vs.size() > 1){ u.vs.erase(x); u.s--; }else { if(u.ch[0] && u.ch[1]){ int d2 = nds[u.ch[0]].r > nds[u.ch[1]].r ? 1:0; rot(o,d2); rmov(nds[o].ch[d2],x); }else { delt(o); if(!u.ch[0]) o = u.ch[1]; else o = u.ch[0]; } } } if(o) mt(o); } int Rank(int o,int x) { Node &u = nds[o]; int d = cmp(u.v,val[x]); if(d == 1) return Rank(u.ch[1],x); int s = nds[u.ch[1]].s; if(d == 0) return s+(int)u.vs.size()+Rank(u.ch[0],x); return s+1; } int Kth(int o,int k) { if(!o || k <= 0 || k > nds[o].s) return -1;// Node &u = nds[o]; int s = nds[u.ch[1]].s; if(k == s+1) return *(u.vs.begin()); if(k <= s) return Kth(u.ch[1],k); return Kth(u.ch[0],k-s-(int)u.vs.size()); } void rmvTree(int o) { if(nds[o].ch[0]) rmvTree(nds[o].ch[0]); if(nds[o].ch[1]) rmvTree(nds[o].ch[1]); delt(o); } //#define LOCAL int main() { #ifdef LOCAL freopen("data.txt","r",stdin); #endif int N,M; char op[50]; initTreap(maxn*2); int root = 0; while(~scanf("%d%d",&N,&M)){ if(root) rmvTree(root); root = 0; fill(st,st+N,0); fill(val,val+N,0); fill(lst,lst+N,-5); memset(pen,0,sizeof(pen)); for(int i = 0; i < N; i++){ lsa[i] = -N+i; inst(root,i); } int c = 0; while(~scanf("%s",op)&&*op != ‘C‘){ if(*op == ‘S‘){ int t,x,re; char pro; scanf("%d:%d:%c:%d",&t,&x,&pro,&re); int p = pro-‘A‘; if(t - lst[x] < 5 || (st[x]&(1<<p))) continue; lst[x] = t; if(re == 1){ printf("[%d][%c]\n",x,pro); rmov(root,x); lsa[x] = ++c; st[x] |= 1<<p; val[x] += MAXPEN-pen[x][p]-t; inst(root,x); }else pen[x][p] += 20; }else if(*op == ‘R‘){ int x; scanf("%d",&x); printf("%d\n",Rank(root,x)); }else if(*op == ‘T‘){ int k; scanf("%d",&k); printf("%d\n",Kth(root,k)); } } scanf("%s",op); puts(""); } return 0; }
标签:
原文地址:http://www.cnblogs.com/jerryRey/p/4821087.html