博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ural1439 Battle with You-Know-Who
阅读量:5146 次
发布时间:2019-06-13

本文共 6067 字,大约阅读时间需要 20 分钟。

Battle with You-Know-Who

Time limit: 2.0 second
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 number
M (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.

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.

Sample

input output
20 7L 5D 5L 4L 5D 5L 4L 5
54647

 

分析:参考了两个做法,第一个比较玄,不太好理解,只能写几个证明貌似是对的;

   第二个就是treap树了,参考http://blog.csdn.net/u011686226/article/details/39005875;

   treap树插入询问第K大,询问时二分,询问mid时小于等于mid数有y个,那么mid是第mid-y大的数;

代码:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define rep(i,m,n) for(i=m;i<=n;i++)#define rsp(it,s) for(set
::iterator it=s.begin();it!=s.end();it++)#define mod 1000000007#define inf 0x3f3f3f3f#define vi vector
#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
#define Lson L, mid, rt<<1#define Rson mid+1, R, rt<<1|1const 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
ans;i--)a[i]=a[i-1]; a[++now]=2e9; a[ans]=k; } } //system("Pause"); return 0;}

treap树:

#include 
#include
#include
#include
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;}

转载于:https://www.cnblogs.com/dyzll/p/5836256.html

你可能感兴趣的文章
C++ 面向对象 类成员函数this指针
查看>>
inline函数的总结
查看>>
SPSS-生存分析
查看>>
【Jquery】$.Deferred 对象
查看>>
Python字符编码
查看>>
leetcode 49. 字母异位词分组(Group Anagrams)
查看>>
NSPredicate的使用,超级强大
查看>>
自动分割mp3等音频视频文件的脚本
查看>>
财务结算的目的和一般流程
查看>>
Myeclipse 优化1
查看>>
[BJOI2012]最多的方案(记忆化搜索)
查看>>
生成了一个严重警告并将其发送到远程终结点。这会导致连接终止。TLS 协议所定义的严重错误代码是...
查看>>
判断字符串是否为空的注意事项
查看>>
布兰诗歌
查看>>
vscode 中 eslint 相关配置
查看>>
老李分享:5个衡量软件质量的标准
查看>>
Xcode部分插件无法使用识别的问题
查看>>
set学习记录
查看>>
用函数写注册功能
查看>>
JVM笔记4:Java内存分配策略
查看>>