HDU 3727 Jewel 主席树
2016-08-07 17:07
253 查看
这是自己写的第一个markdown博文,多说几句废话哈哈哈哈,其实自己对用什么东西写博文没什么想法,但是啊,人要是不喜欢学习新的东西,就会变low了啊
题目链接:点这里点这里
题意:一个人对一个序列不断进行如下4种操作
1. Insert x :在这个序列的末端放入x这个数字(0<x<231)
可能你在题目地址看题目的时候会看见题目内的写法是0<x<231,请记住下面一张图片……
2. Query_1 s t k :查询当前序列的[s,t]区间上的第k小的数字大小
3. Query_2 x :查询当前序列中,x这个数的rank
4. Query_3 k :查询当前整个序列中第k小的数字大小
思路:其实没什么想法啊……就是差不多裸的主席树,离线求就好了,至于Query_2,也是离线,离散化后,用树状数组求。
如果自己还可以的话,希望可以多做几个主席树的题,然后总结成一个系列,所以这片文作为一个坑先放这里,愿自己以后不会这么弱了……
题目链接:点这里点这里
题意:一个人对一个序列不断进行如下4种操作
1. Insert x :在这个序列的末端放入x这个数字(0<x<231)
可能你在题目地址看题目的时候会看见题目内的写法是0<x<231,请记住下面一张图片……
2. Query_1 s t k :查询当前序列的[s,t]区间上的第k小的数字大小
3. Query_2 x :查询当前序列中,x这个数的rank
4. Query_3 k :查询当前整个序列中第k小的数字大小
思路:其实没什么想法啊……就是差不多裸的主席树,离线求就好了,至于Query_2,也是离线,离散化后,用树状数组求。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define lowbit(x) (x&(-x)) #define MS(x,y) memset(x,y,sizeof(x)) typedef long long LL; const int MAXN=100000+5; char op[10]; int a[MAXN],b[MAXN],c[MAXN]; LL ans[5]; int n,q; struct Node{ int l,r,k,type; }node[35000*3+5+MAXN]; int tr[MAXN]; void add(int x){ for(;x<MAXN;x+=lowbit(x)) ++tr[x]; } int que(int x){ int ret=0; for(;x;x-=lowbit(x)) ret+=tr[x]; return ret; } int tot; int lson[MAXN*50],rson[MAXN*50],val[MAXN*50],idx[MAXN]; int build(int l,int r){ int root=tot++; val[root]=0; if(l!=r){ int mid=(l+r)>>1; lson[root]=build(l,mid); rson[root]=build(mid+1,r); } return root; } int update(int root,int pos,int V){ int newroot=tot++,ret=newroot; val[newroot]=val[root]+V; int l=1,r=n,mid; while(l<r){ mid=(l+r)>>1; if(pos<=mid){ lson[newroot]=tot++;rson[newroot]=rson[root]; newroot=lson[newroot];root=lson[root]; r=mid; } else{ lson[newroot]=lson[root];rson[newroot]=tot++; newroot=rson[newroot];root=rson[root]; l=mid+1; } val[newroot]=val[root]+V; } return ret; } int query(int lroot,int rroot,int k){ int l=1,r=n,mid; while(l<r){ mid=(l+r)>>1; if(val[lson[lroot]]-val[lson[rroot]]>=k){ lroot=lson[lroot];rroot=lson[rroot]; r=mid; } else{ k-=val[lson[lroot]]-val[lson[rroot]]; lroot=rson[lroot];rroot=rson[rroot]; l=mid+1; } } return l; } int main(){//freopen("3727.in","r",stdin); int Q,kase=0; while(~scanf("%d",&Q)){ MS(tr,0); MS(ans,0); n=q=0; int l,r,k; while(Q--){ scanf("%s",op); if(op[0]=='I'){ scanf("%d",&a[++n]); b =a ; node[++q].k=a ; node[q].type=0; } else{ if(op[6]=='1'){ scanf("%d%d%d",&l,&r,&k); node[++q].l=l; node[q].r=r; node[q].k=k; node[q].type=1; } else if(op[6]=='2'){ scanf("%d",&k); node[++q].k=k; node[q].type=2; } else{ scanf("%d",&k); node[++q].l=1; node[q].r=n; node[q].k=k; node[q].type=3; } } } sort(b+1,b+1+n); tot=0; idx[n+1]=build(1,n); for(int i=n;i;--i){ int pos=lower_bound(b+1,b+1+n,a[i])-b; idx[i]=update(idx[i+1],pos,1); } for(int i=1;i<=q;++i){ if(node[i].type){ if(node[i].type==2){ int pos=lower_bound(b+1,b+1+n,node[i].k)-b; ans[2]+=que(pos); } else{ ans[node[i].type]+= b[query(idx[node[i].l],idx[node[i].r+1],node[i].k)]; } } else{ int pos=lower_bound(b+1,b+1+n,node[i].k)-b; add(pos); } } printf("Case %d:\n%I64d\n%I64d\n%I64d\n",++kase,ans[1],ans[2],ans[3]); } }
如果自己还可以的话,希望可以多做几个主席树的题,然后总结成一个系列,所以这片文作为一个坑先放这里,愿自己以后不会这么弱了……
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)