标签:
input | output |
---|---|
20 7 L 5 D 5 L 4 L 5 D 5 L 4 L 5 |
5 4 6 4 7
|
分析:参考了两个做法,第一个比较玄,不太好理解,只能写几个证明貌似是对的;
第二个就是treap树了,参考http://blog.csdn.net/u011686226/article/details/39005875;
treap树插入询问第K大,询问时二分,询问mid时小于等于mid数有y个,那么mid是第mid-y大的数;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <hash_map> #include <queue> #include <stack> #include <vector> #include <list> #define rep(i,m,n) for(i=m;i<=n;i++) #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define Lson L, mid, rt<<1 #define Rson mid+1, R, rt<<1|1 const int maxn=1e5+10; const int dis[][2]={0,1,-1,0,0,-1,1,0}; using namespace std; using namespace __gnu_cxx; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p%mod;p=p*p%mod;q>>=1;}return f;} int n,m,k,t,a[maxn],now; char op[2]; int main() { int i,j; a[0]=2e9; scanf("%d%d",&m,&n); while(n--) { scanf("%s%d",op,&k); int l=0,r=now,ans; while(l<=r) { int mid=l+r>>1; if(a[mid]>k)ans=mid,r=mid-1; else l=mid+1; } if(op[0]==‘L‘)printf("%d\n",k+ans); else { for(int i=ans;i<now;i++)a[i]--; for(int i=now;i>ans;i--)a[i]=a[i-1]; a[++now]=2e9; a[ans]=k; } } //system("Pause"); return 0; }
treap树:
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int maxm = 100010; int ch[maxm][2], r[maxm], val[maxm], sum[maxm], num[maxm], cnt, root; void Node(int &rt, int x){ rt = ++cnt; ch[rt][0] = ch[rt][1] = 0; r[rt] = rand(); val[rt] = x; if(cnt > 1) { sum[rt] = 1; num[rt] = 1; } else { sum[rt] = 0; num[rt] = 0; } } void maintain(int rt){ sum[rt] = sum[ch[rt][0]]+sum[ch[rt][1]]+num[rt]; } void init() { ch[0][0] = ch[0][1] = 0; r[0] = (1LL<<31)-1; val[0] = 0; sum[0] = 0; cnt = 0; root = 0; Node(root, 2000000001); } void rotate(int &rt, int d){ int k = ch[rt][d^1]; ch[rt][d^1] = ch[k][d]; ch[k][d] = rt; maintain(rt); maintain(k); rt = k; } void insert(int &rt, int x){ if(!rt){ Node(rt, x); return; } else{ if(x == val[rt]) num[rt]++; else { int d = x < val[rt] ? 0 : 1; insert(ch[rt][d], x); if(r[ch[rt][d]] < r[rt]) rotate(rt, d^1); } } maintain(rt); } /*void remove(int &rt, int x){ if(val[rt] == x){ val[rt]--; if(!val[rt]){ if(!ch[rt][0] && !ch[rt][1]) { rt = 0; return; } else{ int d = r[ch[rt][0]] > r[ch[rt][1]] ? 1 : 0; rotate(rt, d); remove(ch[rt][d], x); } else{ } } } else remove(ch[rt][x>val[rt]], x); maintain(rt); }*/ int kth(int rt, int k){ if(rt == 0) return 0; if(val[rt] <= k) return sum[ch[rt][0]]+num[rt]+kth(ch[rt][1], k); return kth(ch[rt][0], k); } int main() { int n, m; while(scanf("%d %d", &n, &m) != EOF) { init(); while(m--) { char s[10]; int x; scanf("%s %d", s, &x); int l = 1, r = n, ans; while(l<=r) { int mid=l+r>>1,y=kth(root,mid); if(x<=mid-y)ans=mid,r=mid-1; else l=mid+1; } if(s[0] == ‘L‘) { printf("%d\n", ans); } else { insert(root, ans); } } } //system("pause"); return 0; }
标签:
原文地址:http://www.cnblogs.com/dyzll/p/5836256.html