hdu 5412 CRB and Queries 求动态区间第k小 树套树
来源:互联网 发布:手机淘宝社区 编辑:程序博客网 时间:2024/05/29 17:43
题意:
给n个数,然后有两个操作
1.把第i个点的值修改为v
2.求[l,r]区间内第k小的数
树状数组+平衡树。
我写了两份代码:树状数组+SBT和树状数组+Treap
代码:
//author: CHC//First Edit Time: 2015-08-20 14:10#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <vector>#include <map>#include <queue>#include <set>#include <algorithm>#include <limits>#include <time.h>using namespace std;typedef long long LL;const int MAXN=1e+5 + 1000;const int INF = numeric_limits<int>::max();const LL LL_INF= numeric_limits<LL>::max();struct SBT{ int left,right,size,key; void Init() { left=right=0; size=1; }}tree[MAXN*30];int tot,root[MAXN<<2],n;void left_rotate(int &x)//左旋{ int y=tree[x].right; tree[x].right=tree[y].left; tree[y].left=x; tree[y].size=tree[x].size; tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1; x=y;}void right_rotate(int &x)//右旋{ int y=tree[x].left; tree[x].left=tree[y].right; tree[y].right=x; tree[y].size=tree[x].size; tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1; x=y;}void maintain(int &x,int flag){ if(flag==0) { if(tree[tree[tree[x].left].left].size > tree[tree[x].right].size) right_rotate(x); else if(tree[tree[tree[x].left].right].size > tree[tree[x].right].size) left_rotate(tree[x].left),right_rotate(x); else return; } else { if(tree[tree[tree[x].right].right].size > tree[tree[x].left].size) left_rotate(x); else if(tree[tree[tree[x].right].left].size > tree[tree[x].left].size) right_rotate(tree[x].right),left_rotate(x); else return; } maintain(tree[x].left,0); maintain(tree[x].right,1); maintain(x,0); maintain(x,1);}//插入元素,相同元素放在右子树中void insert(int &x,int key){ if(x==0) { x=++tot; tree[x].Init(); tree[x].key=key; } else { tree[x].size++; if(key<tree[x].key)insert(tree[x].left,key); else insert(tree[x].right,key); maintain(x,key>=tree[x].key); }}//删除key值的元素int del(int &x,int key){ if(!x)return 0; tree[x].size--; if(key==tree[x].key || (key<tree[x].key&&tree[x].left==0) || (key>tree[x].key&&tree[x].right==0)) { if(tree[x].left && tree[x].right) { int p=del(tree[x].left,key+1); tree[x].key=tree[p].key; return p; } else { int p=x; x=tree[x].left+tree[x].right; return p; } } else return del(key<tree[x].key?tree[x].left:tree[x].right,key);}int _rank(int x,int val){ if(x==0)return 0; if(tree[x].key<=val)return tree[tree[x].left].size+1+_rank(tree[x].right,val); return _rank(tree[x].left,val);}void print(int x,int d){ if(!x)return ; printf("%d %d\n",tree[x].key,d); print(tree[x].left,d+1);print(tree[x].right,d+1);}int A[MAXN];void Add(int x,int v){ while(x<=n){ //printf("x:%d\n",x); insert(root[x],v); x+=x&-x; }}void Del(int x,int v){ while(x<=n){ del(root[x],v); x+=x&-x; }}int Sum(int x,int v){ int cnt=0; while(x>0){ cnt+=_rank(root[x],v); x-=x&-x; } return cnt;}struct Q { int type,l,r,v;}cs[MAXN];int res[MAXN*2];int main(){ //int size = 256 << 20; // 256MB //char *p = (char*)malloc(size) + size; //__asm__("movl %0, %%esp\n" :: "r"(p)); //freopen("1007.in","r",stdin); //freopen("10071.out","w",stdout); //time_t now=clock(); int q; while(~scanf("%d",&n)){ memset(root,0,sizeof(root)); tot=0; res[0]=0; for(int i=1;i<=n;i++)scanf("%d",&A[i]),res[++res[0]]=A[i]; scanf("%d",&q); for(int i=0;i<q;i++){ scanf("%d",&cs[i].type); if(cs[i].type==1){ scanf("%d%d",&cs[i].l,&cs[i].v); res[++res[0]]=cs[i].v; } else { scanf("%d%d%d",&cs[i].l,&cs[i].r,&cs[i].v); } } sort(res+1,res+1+res[0]); res[0]=unique(res+1,res+1+res[0])-res-1; for(int i=0;i<q;i++){ if(cs[i].type==1){ cs[i].v=lower_bound(res+1,res+1+res[0],cs[i].v)-res; } } //printf("res0:%d\n",res[0]); //for(int i=1;i<=res[0];i++)printf("%d ",res[i]); //puts(""); for(int i=1;i<=n;i++)A[i]=lower_bound(res+1,res+1+res[0],A[i])-res; //for(int i=1;i<=n;i++)printf("%d ",A[i]); //puts(""); //build(1,n,1); //print(root[1],0); //puts("here__"); for(int i=1;i<=n;i++){ Add(i,A[i]); } //puts("here"); for(int i=0;i<q;i++){ if(cs[i].type==1){ //update(1,n,1,cs[i].l,cs[i].v); Del(cs[i].l,A[cs[i].l]); Add(cs[i].l,cs[i].v); A[cs[i].l]=cs[i].v; } else { int l=1,r=res[0],ans=res[0]; while(l<=r){ int mid=(l+r)>>1; int t=Sum(cs[i].r,mid)-Sum(cs[i].l-1,mid); if(t>=cs[i].v){ ans=mid; r=mid-1; } else l=mid+1; } printf("%d\n",res[ans]); } } } //printf("%.2lf\n",1.0*(clock()-now)/CLOCKS_PER_SEC); return 0;}
代码2:
//author: CHC//First Edit Time: 2015-08-20 12:15#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <set>#include <vector>#include <map>#include <queue>#include <set>#include <algorithm>#include <limits>using namespace std;typedef long long LL;const int MAXN=1e+5 + 1000;const int INF = numeric_limits<int>::max();const LL LL_INF= numeric_limits<LL>::max();class Treap { public: struct node { node *ch[2]; int v,p,sz; node(int _v,node *_n){ v=_v; ch[0]=ch[1]=_n; p=rand(); sz=1; } void update(){sz=ch[0]->sz+ch[1]->sz+1;} void fixch(node *left,node *right){ch[0]=left;ch[1]=right;} }; node *root,*null; Treap(){ null=new node(0,0); null->fixch(null,null); null->sz=0; root=null; } void rotate(node *&t,bool d){ node *_t=t->ch[d]; t->ch[d]=_t->ch[!d]; _t->ch[!d]=t; t->update(); _t->update(); t=_t; } void __insert(node *&t,int val){ if(t==null){ t=new node(val,null); return ; } bool d=(t->v < val); __insert(t->ch[d],val); if(t->ch[d]->p < t->p)rotate(t,d); t->update(); } void __del(node *&t,int val){ if(t==null)return ; if(t->v==val){ node *tmp=t; if(t->ch[0]==null){ t=t->ch[1]; delete tmp; return ; } if(t->ch[1]==null){ t=t->ch[0]; delete tmp; return ; } bool d=t->ch[1]->p < t->ch[0]->p; rotate(t,d); __del(t->ch[!d],val); } else { bool d=(t->v < val); __del(t->ch[d],val); } t->update(); } int __rank(node *t,int val){ if(t==null)return 0; if(t->v <= val)return t->ch[0]->sz+1+__rank(t->ch[1],val); //return t->ch[1]->sz+1+__rank(t->ch[0],val); return __rank(t->ch[0],val); } void __clean(node *&t){ if(t==null)return ; if(t->ch[0]!=null)__clean(t->ch[0]); if(t->ch[1]!=null)__clean(t->ch[1]); delete t; t=null; } void insert(int val){ __insert(root,val); } void del(int val){ __del(root,val); } int rank(int val){ return __rank(root,val);} void clean(){ __clean(root); } ~Treap(){ clean(); delete null; }}tr[MAXN];#define lson L,mid,rt<<1#define rson mid+1,R,rt<<1|1int A[MAXN],n;void Add(int pos,int v){ while(pos<=n){ tr[pos].insert(v); pos+=pos&-pos; }}void Del(int pos,int v){ while(pos<=n){ tr[pos].del(v); pos+=pos&-pos; }}int Sum(int pos,int v){ int cnt=0; while(pos>0){ cnt+=tr[pos].rank(v); pos-=pos&-pos; } return cnt;}struct Q { int type,l,r,v;}cs[MAXN];int res[MAXN*2];int main(){ //int size = 256 << 20; // 256MB //char *p = (char*)malloc(size) + size; //__asm__("movl %0, %%esp\n" :: "r"(p)); //freopen("1007.in","r",stdin); //freopen("10071.out","w",stdout); while(~scanf("%d",&n)){ res[0]=0; for(int i=1;i<=n;i++)scanf("%d",&A[i]),res[++res[0]]=A[i]; int q; //printf("%d\n",query(1,n,1,1,n,4)); scanf("%d",&q); for(int i=0;i<q;i++){ scanf("%d",&cs[i].type); if(cs[i].type==1){ scanf("%d%d",&cs[i].l,&cs[i].v); res[++res[0]]=cs[i].v; } else { scanf("%d%d%d",&cs[i].l,&cs[i].r,&cs[i].v); } } sort(res+1,res+1+res[0]); res[0]=unique(res+1,res+1+res[0])-res-1; //printf("res0:%d\n",res[0]); //for(int i=1;i<=res[0];i++)printf("%d ",res[i]); //puts(""); for(int i=1;i<=n;i++){ A[i]=lower_bound(res+1,res+1+res[0],A[i])-res; } //build(1,n,1); for(int i=0;i<q;i++){ if(cs[i].type==1){ cs[i].v=lower_bound(res+1,res+1+res[0],cs[i].v)-res; } } for(int i=0;i<=n;i++)tr[i].clean(); for(int i=1;i<=n;i++){ Add(i,A[i]); } for(int i=0;i<q;i++){ if(cs[i].type==1){ //while(A[cs[i].l]<=0||A[cs[i].l]>res[0]); Del(cs[i].l,A[cs[i].l]); Add(cs[i].l,cs[i].v); A[cs[i].l]=cs[i].v; //update(1,n,1,cs[i].l,cs[i].v); } else { int l=1,r=res[0],ans=res[0]; while(l<=r){ int mid=(l+r)>>1; int t=Sum(cs[i].r,mid)-Sum(cs[i].l-1,mid); //if(query(1,n,1,cs[i].l,cs[i].r,mid)>=cs[i].v){ if(t>=cs[i].v){ ans=mid; r=mid-1; } else l=mid+1; } printf("%d\n",res[ans]); } } } return 0;}
0 0
- hdu 5412 CRB and Queries 求动态区间第k小 树套树
- hdu 5412 CRB and Queries(动态求区间第k小+整体二分)
- HDU 5412 CRB and Queries 求区间第k小 CDQ分治+整体二分
- 整体二分,区间第K小(CRB and Queries,HDU 5412)
- hdu 5412 CRB and Queries(线段树套笛卡尔树 - 动态区间第k大)
- HDU 5412 CRB and Queries(区间第K大 树套树 按值建树)
- hdu 5412 CRB and Queries(树套树模板,区间第K大)
- hdu 5412 CRB and Queries 2015多校联合训练赛#10 分治 求区间第k大数
- CRB and Queries(动态区间求第k小数模板题:线段树套平衡树)
- hdu 5412 CRB and Queries(动态区间第k大值,区间能修改)(整体二分,树状数组套平衡树,线段树套treap)
- 【HDU5412】CRB and Queries-整体二分:带修改区间第K小
- hdu 5412 CRB and Queries
- HDU 5412 CRB and Queries 树套树 BIT+PBDS
- Hdu-5412 CRB and Queries(整体二分)
- HDU 5412 CRB and Queries 整体二分
- HDU 5412 CRB and Queries (Kth number 整体二分 动态转静态)
- HDU 5412 CRB and Queries【整体二分+树状数组】
- HDU 5412 CRB and Queries(整体二分)
- 去掉eclipse或myeclipse中的断点
- hdu5135(状态压缩DP)
- 栈和队列
- 搭建时间服务器和设置FQDN主机名
- ftp服务器遇到的问题
- hdu 5412 CRB and Queries 求动态区间第k小 树套树
- 轻松python专题--文本
- 读书有感之《从零到一》
- 选择排序
- 零基础学C语言 笔记三 三种方法交换两个变量的值
- IOS_代码实现树形导航
- MVC初步理解
- c++引用返回值
- 【android ndk】macos环境下Android Studio中利用gradle编译jni模块及配置