HDU-3727 Jewel(查询第K大是几,以及数字是第几大)
2017-07-19 11:28
375 查看
题意:
插入操作
1查询 S~T 第K是几
2查询 X是当前的第几小
3操作当前第K小是几
思路:
建立主席树 ,三种基本操作
数组开小会TLE。
插入操作
1查询 S~T 第K是几
2查询 X是当前的第几小
3操作当前第K小是几
思路:
建立主席树 ,三种基本操作
数组开小会TLE。
#include <iostream> #include <stdio.h> #include <algorithm> #include <cstring> #include <vector> using namespace std; struct node { int lc,rc,num; } tree[2000010]; int a[200005],rnu,cnt,now; int num[200005]; int root[200005]; long long ans1,ans2,ans3; struct oper { int kind,l,r,k,num; } choose[200005]; void build(int &i,int l,int r) { tree[++cnt]=tree[i]; i=cnt; if(l==r) return ; int mid=(l+r)>>1; build(tree[i].lc,l,mid); build(tree[i].rc,mid+1,r); } void update(int &i,int l,int r,int num ) { tree[++cnt]=tree[i]; i=cnt; tree[i].num++; if(l==r) { return ; } int mid=(l+r)>>1; if(num<=a[mid]) { update(tree[i].lc,l,mid,num); } else update(tree[i].rc,mid+1,r,num); } int query(int i,int j,int l,int r,int k) { if(l==r) return a[l]; int mid=(l+r)>>1; if(tree[tree[j].lc].num-tree[tree[i].lc].num>=k) return query(tree[i].lc,tree[j].lc,l,mid,k); else return query(tree[i].rc,tree[j].rc,mid+1,r,k-(tree[tree[j].lc].num-tree[tree[i].lc].num)); } int Query(int i,int l,int r,int num) { if(a[r]<=num) return tree[i].num; int mid=(l+r)>>1; if(num<=a[mid]) return Query(tree[i].lc,l,mid,num); else return tree[tree[i].lc].num+Query(tree[i].rc,mid+1,r,num); } int main() { int cs=1,n; while(scanf("%d",&n)!=EOF) { printf("Case %d:\n",cs++); char op[10]; cnt=now=rnu=0; for(int i=1; i<=n; i++) { scanf("%s",op); if(op[0]=='I') { choose[i].kind=0; scanf("%d",&choose[i].num); a[++rnu]=choose[i].num; } else { if(op 4000 [6]=='1') { choose[i].kind=1; scanf("%d%d%d",&choose[i].l,&choose[i].r,&choose[i].k); } else if(op[6]=='2') { choose[i].kind=2; scanf("%d",&choose[i].num); } else { choose[i].kind=3; scanf("%d",&choose[i ].k); } } } sort(a+1,a+1+rnu); rnu=unique(a+1,a+1+rnu)-a-1; build(root[0],1,rnu); ans1=ans2=ans3=0; for(int i=1;i<=n;i++) { if(choose[i].kind==0) { now++; update(root[now]=root[now-1],1,rnu,choose[i].num); } else if(choose[i].kind==1) { ans1+=query( root[ choose[i].l-1 ],root[ choose[i].r ],1,rnu,choose[i].k ); } else if(choose[i].kind==2) { ans2+=Query(root[now],1,rnu,choose[i].num ); } else { ans3+=query(root[0],root[now],1,rnu,choose[i].k); } } printf("%lld\n%lld\n%lld\n",ans1,ans2,ans3); } }
相关文章推荐
- hdu 3727 Jewel 划分数+树状数组 求区间和当前段的第k大数
- HDU 3727 Jewel(划分树 + 二分)
- hdu 5059 判断数字表示方式以及范围合法(int型之内)
- hdu----(5023)A Corrupt Mayor's Performance Art(线段树区间更新以及区间查询)
- hdu 4006 输入新数后输出第k大的数 set以及优先队列2中做法
- hdu 3727:Jewel
- hdu 3727 Jewel(主席树)
- HDU 3727 Jewel 主席树简单题
- HDU 3727 Jewel 简单主席树
- HDU 3727 Jewel 主席树
- hdu 5412(树套树求第k小数字+离散化)
- HDU 3727 Jewel
- HDU 3727 Jewel 可持久化线段树
- hdu 3727 Jewel
- HDU 3727 Jewel 主席树
- HDU 3727 Jewel 主席树
- 【HDU】3727 Jewel
- 查询一个int类型的变量(数字)是否在一个字符串里边(逗号分隔的)以及 sqlif 与case
- 数据数字mongodb 模糊查询以及$type使用
- Hdu 3726 Graph and Queries(删边,查询第k大,修改点值)