AVL平衡树(山东省选 郁闷的小J)
来源:互联网 发布:ubuntu查看64位 32位 编辑:程序博客网 时间:2024/06/11 17:06
题目描述:
小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架。虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他面临着被解雇的危险,这也正是他所郁闷的。
具体说来,书架由N个书位组成,编号从1到N。每个书位放着一本书,每本书有一个特定的编码。
小J的工作有两类:
- 图书馆经常购置新书,而书架任意时刻都是满的,所以只得将某位置的书拿掉并换成新购的书。
- 小J需要回答顾客的查询,顾客会询问某一段连续的书位中某一特定编码的书有多少本。
例如,共5个书位,开始时书位上的书编码为1,2,3,4,5
一位顾客询问书位1到书位3中编码为“2”的书共多少本,得到的回答为:1
一位顾客询问书位1到书位3中编码为“1”的书共多少本,得到的回答为:1
此时,图书馆购进一本编码为“1”的书,并将它放到2号书位。
一位顾客询问书位1到书位3中编码为“2”的书共多少本,得到的回答为:0
一位顾客询问书位1到书位3中编码为“1”的书共多少本,得到的回答为:2
……
你的任务是写一个程序来回答每个顾客的询问。
输入:
第一行两个整数N,M,表示一共N个书位,M个操作。
接下来一行共N个整数数A1,A2…AN,Ai表示开始时位置i上的书的编码。
接下来M行,每行表示一次操作,每行开头一个字符
若字符为‘C’,表示图书馆购进新书,后接两个整数A(1<=A<=N),P,表示这本书被放在位置A上,以及这本书的编码为P。
若字符为‘Q’,表示一个顾客的查询,后接三个整数A,B,K(1<=A<=B<=N),表示查询从第A书位到第B书位(包含A和B)中编码为K的书共多少本。
(1<=N,M<=100000,所有出现的书的编码为不大于2147483647的正数。)
输出: 对每一个顾客的查询,输出一个整数,表示顾客所要查询的结果。样例:
(如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
5 51 2 3 4 5Q 1 3 2Q 1 3 1C 2 1Q 1 3 2Q 1 3 1
样例输出
1102
这道题思维难度不大,很容易就可以想出平衡树的正解,难在实现。但其实,将平衡树的模板稍微修改即可过
题解:
这里给出两个思路,一种是对于每种书都做一个平衡树,按那个书的位置排序
第二种是按书的编号排序,编号相同用位置排序,这里采用的是第二种思路
这里是用了结构体重定义运算符来实现的,代码和模板简直一模一样。。。
code:
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<cstdlib>#include<algorithm> typedef long long LL;const int MAXN=200005;using namespace std;struct Temp{ int data,pos; Temp(){} Temp(int a,int b){ data=a,pos=b; } bool operator ==(const Temp &b)const{ return data==b.data&&pos==b.pos; } bool operator<(const Temp &b)const{ if(data==b.data) return pos<b.pos; else return data<b.data; } bool operator>(const Temp &b)const{ if(data==b.data) return pos>b.pos; else return data>b.data; } bool operator<=(const Temp &b)const{ return !(*this>b); } bool operator>=(const Temp &b)const{ return !(*this<b); }};struct node{ int lc,rc,h,num; Temp data;}tree[MAXN+5];int cnt,root,arr[MAXN],N,M; inline void Read(int &Ret){ char ch;bool flag=0; for(;ch=getchar(),ch<'0'||ch>'9';)if(ch=='-')flag=1; for(Ret=ch-'0';ch=getchar(),'0'<=ch&&ch<='9';Ret=Ret*10+ch-'0'); flag&&(Ret=-Ret);}inline void update(int i){ tree[i].h=max(tree[tree[i].lc].h,tree[tree[i].rc].h)+1; tree[i].num=tree[tree[i].lc].num+tree[tree[i].rc].num+1;}int zig(int i){ int t=tree[i].lc; tree[i].lc=tree[t].rc; tree[t].rc=i; update(i); update(t); return t;}int zag(int i){ int t=tree[i].rc; tree[i].rc=tree[t].lc; tree[t].lc=i; update(i); update(t); return t;}int zigzag(int i){ tree[i].rc=zig(tree[i].rc); return zag(i);}int zagzig(int i){ tree[i].lc=zag(tree[i].lc); return zig(i);} void maintain(int &i){ if(tree[tree[i].lc].h==tree[tree[i].rc].h+2) { int t=tree[i].lc; if(tree[tree[t].rc].h==tree[tree[i].rc].h+1) i=zagzig(i); else if(tree[tree[t].lc].h==tree[tree[i].rc].h+1) i=zig(i); } else if(tree[tree[i].rc].h==tree[tree[i].lc].h+2) { int t=tree[i].rc; if(tree[tree[t].lc].h==tree[tree[i].lc].h+1) i=zigzag(i); else if(tree[tree[t].rc].h==tree[tree[i].lc].h+1) i=zag(i); } update(i);}void Insert(int &i,Temp x){ if(!i) { tree[++cnt].data=x; tree[cnt].h=tree[cnt].num=1; i=cnt; return; } if(x<=tree[i].data) Insert(tree[i].lc,x); else Insert(tree[i].rc,x); maintain(i); return;}Temp Delete(int &i,Temp x){ Temp res; if(tree[i].data==x||(x>tree[i].data&&!tree[i].rc)||(x<tree[i].data&&!tree[i].lc)) { res=tree[i].data; if(!tree[i].rc||!tree[i].lc) {i=tree[i].rc+tree[i].lc;return res;} else tree[i].data=Delete(tree[i].lc,x); } else { if(x<tree[i].data) res=Delete(tree[i].lc,x); else res=Delete(tree[i].rc,x); } maintain(i); return res;}int getrank(int i,Temp x){ if(!i) return 0; if(x<=tree[i].data) return getrank(tree[i].lc,x); else return tree[tree[i].lc].num+1+getrank(tree[i].rc,x);}int Query(int a,int b,int num){ int x=getrank(root,Temp(num,b)); int y=getrank(root,Temp(num,a)); if(arr[b]==num) x++; return x-y;}int main(){ Read(N); Read(M); for(int i=1;i<=N;i++) { scanf("%d",&arr[i]); Insert(root,Temp(arr[i],i)); } int a,b,k,p; char ord[5]; for(int i=1;i<=M;i++) { scanf("%s",ord); switch(ord[0]) { case 'C': scanf("%d%d",&a,&p); Delete(root,Temp(arr[a],a)); Insert(root,Temp(p,a));arr[a]=p; break; case 'Q': scanf("%d%d%d",&a,&b,&k); printf("%d\n",Query(a,b,k)); break; } } return 0;}
- AVL平衡树(山东省选 郁闷的小J)
- 【洛谷】2464 [SDOI2008]郁闷的小J 平衡树
- AVL树 郁闷的出纳员 [NOI 2004] [平衡树解法]
- [SMOJ2212]郁闷的小J
- AVL(平衡树)
- AVL树的操作——郁闷的出纳员,平衡树解法
- 平衡二叉树(AVL)的实现
- AVL(平衡)树的旋转
- AVL(高度平衡的二叉树)
- 平衡二叉树(AVL树)的平衡旋转
- AVL平衡树的旋转
- AVL平衡树的实现
- AVL树的平衡过程
- AVL平衡树的旋转
- AVL树的旋转平衡
- AVL树(平衡树)
- 平衡树(AVL)详解
- 平衡树(AVL)详解
- Android系统服务分析之服务注册过程
- 图像处理算法——卷积
- 5-13 Insert or Merge (25分)
- 【PAT】【Advanced Level】1006. Sign In and Sign Out (25)
- manacher算法--最长回文子串
- AVL平衡树(山东省选 郁闷的小J)
- 事件监听器 java.lang.NoClassDefFoundError
- day_04_内存管理
- hdu 2097 水题
- unity3d打包发布Apk流程
- 6/27作业:多态
- MO CALL流程
- 几种网络协议的定义及区别
- 输出按逆时针方向旋进的n*n螺旋方阵