hdu 3727 Jewel(主席树学习第四弹)
2015-10-13 21:11
417 查看
题目链接:
hdu 3727题目大意:
给出n个操作,插入一个数,或者查询:- 查询区间第k大
- 查询某个数的排名
- 查询整体第k大
最后问三种查询的结果之和。
题目分析:
首先对数进行离散化然后对数字建立主席树,第k大的做法详见我的主席树学习第一弹
查询某个数的排名,树状数组直接做就好了,记录每个点是否出现过,然后找到sum(x)就是前缀一共有多少个数,也就是当前数的排名。
AC代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #define MAX 200007 using namespace std; typedef long long LL; int root[MAX],cnt_trees,n,len,h[MAX],hcnt; LL ans1,ans2,ans3; struct Query { int f,s,t,k; void init ( int a , int b ,int c , int d ) {f=a,s=b,t=c,k=d;} }q[MAX<<1]; struct Tree { int l,r; int sum; }tree[4000007]; void build ( int& u , int l , int r ) { u = cnt_trees++; tree[u].sum = 0; if ( l == r ) return; int mid = l+r>>1; build ( tree[u].l , l , mid ); build ( tree[u].r , mid+1 , r ); } void update ( int p , int& u , int l , int r , int x ) { u = cnt_trees++; tree[u] = tree[p]; tree[u].sum++; if ( l == r ) return; int mid = l+r>>1; if ( x > mid ) update ( tree[p].r , tree[u].r , mid+1 , r , x ); else update ( tree[p].l , tree[u].l , l , mid , x ); } int query ( int p , int u , int l , int r , int k ) { int sum = tree[tree[u].l].sum - tree[tree[p].l].sum; if ( l == r ) return l; int mid = l+r>>1; if ( sum >= k ) return query ( tree[p].l , tree[u].l , l , mid , k ); else return query ( tree[p].r , tree[u].r , mid+1 , r , k-sum ); } int c[MAX<<1]; int lowbit ( int x ) { return x&-x; } void add ( int x ) { while ( x < hcnt ) { c[x]++; x += lowbit ( x ); } } int sum ( int x ) { int ret = 0; while ( x ) { ret += c[x]; x -= lowbit ( x ); } return ret; } char s[30]; int main ( ) { int cc = 1; while ( ~scanf ( "%d" , &n ) ) { cnt_trees = 0; len = hcnt = 1; memset ( c , 0 , sizeof ( c ) ); for ( int i = 1 ; i <= n ; i++ ) { int x,y,z; scanf ( "%s" , s ); if ( s[0] == 'I' ) { q[i].f = 0; scanf ( "%d" , &q[i].k ); h[hcnt++] = q[i].k; } else { int id = s[6]-48; if ( id == 1 ) scanf ( "%d%d%d" , &x , &y , &z ); else scanf ( "%d" , &z ); q[i].init ( id , x , y , z ); } } sort ( h+1 , h+hcnt ); build ( root[0] , 1 , hcnt-1 ); ans1 = ans2 = ans3 = 0; for ( int i = 1 ; i <= n ; i++ ) { if ( q[i].f == 0 ) { int x = lower_bound ( h , h+hcnt , q[i].k )-h; update ( root[len-1] , root[len] , 1 , hcnt-1 , x ); add ( x ); len++; } else if ( q[i].f == 1 ) ans1 += h[query ( root[q[i].s-1] , root[q[i].t] , 1 , hcnt-1 , q[i].k )]; else if ( q[i].f == 2 ) { int x = lower_bound ( h , h+hcnt , q[i].k )-h; ans2 += sum(x); } else if ( q[i].f == 3 ) ans3 += h[query ( root[0] , root[len-1] , 1 , hcnt-1 , q[i].k )]; } printf ( "Case %d:\n" , cc++ ); printf ( "%I64d\n%I64d\n%I64d\n" , ans1 , ans2 , ans3 ); } }
相关文章推荐
- Codeforces Coder-Strike 2014 - Finals (online edition, Div. 1)
- HDU 1166 敌兵布阵
- POJ 2352 Stars
- PAT 1057 Stack (30)
- poj 2352
- 树状数组
- hdu 4630 No Pain No Game 树状数组
- 树状数组区间求和的三种模型
- [BZOJ2006][NOI2010][RMQ/主席树][二叉堆]超级钢琴
- HDOJ1166 敌兵布阵 树状数组
- 二维树状数组
- Hoj 2275 Number Sequence
- POJ3321 Apple Tree
- BZOJ2434 [Noi2011]阿狸的打字机【AC自动机+dfs序+树状数组】
- HDU 3015
- hdu 5147
- 【转载】区间信息的维护与查询(一)——二叉索引树(Fenwick树、树状数组)
- 树状数组模板
- HLG 1400 汽车比赛
- HDU 1556 Color the ball (简单树状数组)