ural1439 Battle with You-Know-Who
Battle with You-Know-Who
Time limit: 2.0 second
Memory limit: 64 MB
Memory limit: 64 MB
Rooms of the Ministry of Magic are enchanted with a spell which enumerates them automatically. The spell works as follows. The first room created at the Ministry got the number 1. When a new room is created by magic, a number-plate appears at once upon the door. The new number is greater by one than the maximal room number existing at the moment. If a room is not needed anymore, then it is destroyed and all the room numbers that are greater than the number of the destroyed room are lessened by one. Thus, the numeration of the rooms at the Ministry always remains continuous.
Harry Potter found out a list of the numbers of the rooms where Lord Voldemort's Horcruxes are stored (A Horcrux is a magical artifact that provides for the owner's immortality). It seems that now it will be easy for Harry to find the Horcruxes and destroy them. But the task turned out to be more complicated. Because of his mysterious bond with Harry, Voldemort knew at once about Harry's discovery, so he transported himself to the Ministry and started to destroy rooms. This means that numbers of rooms are changing, so when Harry looks at a room's door, he doesn't know which number this door had before. But he knows which numbers were on the doors of the rooms that were destroyed by Voldemort, due to the mentioned bond between them.
Help Harry to defeat Voldemort. You don't have to fight Harry's enemy, but you can help him to determine the true numbers of rooms when he looks at their doors.
Input
The first line contains the number of rooms at the Ministry of Magic N (1 ≤ N ≤ 109) and a numberM (1 ≤ M ≤ 105). Each of the subsequent M lines has the following format:
<letter> <number>
where <letter> is one of the letters 'D' (Destroy) or 'L' (Look at), and <number> is the number on the door of the room which is destroyed or at which Harry looks at the moment. It is guaranteed that not more than 104 rooms will be destroyed during the battle.
<letter> <number>
where <letter> is one of the letters 'D' (Destroy) or 'L' (Look at), and <number> is the number on the door of the room which is destroyed or at which Harry looks at the moment. It is guaranteed that not more than 104 rooms will be destroyed during the battle.
Output
The output must contain for each line
L <number>
of the input the true number (which it had before the battle) of the room at which Harry looks. The numbers must be given one in a line.
L <number>
of the input the true number (which it had before the battle) of the room at which Harry looks. The numbers must be given one in a line.
Sample
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; }