HDU 3436 题解
2016-07-06 10:16
393 查看
题目大意
有一个队列,开始时第i个数是i。
有三种操作。
Top x:把x放到队头。
Query x:查询x是第几个数。
Rank x:查询第x个数。
n<=10^8,m<=10^5,x<=n
我的做法
离散化+线段树
把top和query中的x离散化,把用不到的区间缩成一个点。
记下每个数在线段树中的位置,线段树中每个位置中的第一个数。
top:把原来的数删除,添加一个新数。
query:输出x在线段树中的位置到线段树最后一个位置之间数的个数。
rank:查询第x个数。
有一个队列,开始时第i个数是i。
有三种操作。
Top x:把x放到队头。
Query x:查询x是第几个数。
Rank x:查询第x个数。
n<=10^8,m<=10^5,x<=n
我的做法
离散化+线段树
把top和query中的x离散化,把用不到的区间缩成一个点。
记下每个数在线段树中的位置,线段树中每个位置中的第一个数。
top:把原来的数删除,添加一个新数。
query:输出x在线段树中的位置到线段树最后一个位置之间数的个数。
rank:查询第x个数。
#include<cstdio> #include<cstring> #include<algorithm> #include<map> using namespace std; struct tree { int l,r; int v; int sum; tree *ls,*rs; tree() { l=r=sum=0; ls=rs=0; v=0; } }; tree *top; map<int,int> a,b; int left[500010]; int right[500010]; int cnt2=0; void mt(tree *&p) { if(p->l==p->r) return; p->sum=p->ls->sum+p->rs->sum; } void build(tree *&p,int l,int r) { if(!p) p=new tree; p->l=l; p->r=r; p->v=0; p->sum=0; if(p->l==p->r) return; int mid=(l+r)>>1; build(p->ls,l,mid); build(p->rs,mid+1,r); } void insert(tree *&p,int x,int v,int t) { if(p->l==p->r) { p->sum+=t; if(t==1) { a[v]=p->l; b[p->l]=v; } return; } int mid=(p->l+p->r)>>1; if(x<=mid) insert(p->ls,x,v,t); else insert(p->rs,x,v,t); mt(p); } void insert2(tree *&p,int x,int l,int r) { if(p->l==p->r) { p->sum+=r-l+1; p->v=++cnt2; left[cnt2]=l; right[cnt2]=r; return; } int mid=(p->l+p->r)>>1; if(x<=mid) insert2(p->ls,x,l,r); else insert2(p->rs,x,l,r); mt(p); } int query(tree *&p,int l,int r) { if(l<=p->l&&r>=p->r) return p->sum; int s=0; int mid=(p->l+p->r)>>1; if(l<=mid) s+=query(p->ls,l,r); if(r>mid) s+=query(p->rs,l,r); return s; } int rr(tree *&p,int k) { if(p->l==p->r) { if(!p->v) return b[p->l]; return left[p->v]+k-1; } int s=p->rs->sum; if(k<=s) return rr(p->rs,k); return rr(p->ls,k-s); } int d[100010]; int xx[100010]; int e[100010]; int main() { int t; scanf("%d",&t); top=0; int tt=0; while(t--) { memset(d,0,sizeof(d)); memset(xx,0,sizeof(xx)); memset(e,0,sizeof(e)); a.clear(); b.clear(); printf("Case %d:\n",++tt); int n,m; scanf("%d%d",&n,&m); build(top,1,3*m); int i; int x; int cnt=0; int tot=0; for(i=1;i<=m;i++) { char s[10]; scanf("%s%d",s,&xx[i]); if(s[0]=='T') d[i]=1; else if(s[0]=='R') d[i]=2; else d[i]=3; if(d[i]!=2) e[++tot]=xx[i]; } e[++tot]=1; e[++tot]=n; sort(e+1,e+tot+1); tot=unique(e+1,e+tot+1)-e-1; for(i=tot;i>=1;i--) { insert(top,++cnt,e[i],1); if(i!=1&&e[i]!=e[i-1]+1) insert2(top,++cnt,e[i-1]+1,e[i]-1); } for(i=1;i<=m;i++) { x=xx[i]; if(d[i]==1) { int v=a[x]; insert(top,v,x,-1); insert(top,++cnt,x,1); } else if(d[i]==2) printf("%d\n",rr(top,x)); else printf("%d\n",query(top,a[x],cnt)); } } return 0; }
相关文章推荐
- spring mvc在tomcat中get方式中文乱码
- AngularJS实现跨域请求
- oracle统计(当前层级以及所有下级组织机构登录次数总和)
- JAVA自动适配Linux与Windows文件路径分隔符
- cdq分治 -- CF edu13 F Lena and Queries
- linux常用命令举例
- 操作系统精髓与设计原理(原书第6版)——学习笔记(7)
- 生无可恋的一叶知秋#百度刘超事件#
- WARN 02:04:10 Batch of prepared statements for [falcon_gps.gps] is of size 18000, exceeding specified threshold of 5120 by 12880.
- ubuntu查看文件大小
- mac下ppk 转ssh
- Delphi通过ICMP检测与远程主机连接
- Django Admin管理 fields和list_display的区别
- Shiro系列学习 -- 入门篇
- HDU 5296 Annoying problem (树状数组+dfs序+倍增)
- 剑指Offer:面试题11——数值的整数次方(java实现)
- Android开发中setContentView和inflate的区别分析
- 11选5经典技巧 收集的
- WebSocket聊天室
- 图片在父元素中上下居中(vertical-align的有效性)