HDU3727 Jewel(主席树)
来源:互联网 发布:qq酷双项淘宝客 编辑:程序博客网 时间:2024/06/05 09:41
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3727
这题还是挺需要细心的,算是主席树一个挺好的练手题了。
题意:输入n,再输入n个操作,操作有四种
Insert X:插入x到序列末尾
query1 L R X:在当前序列中的[l,r]区间找第x小的数。
query2 X:在当前序列中,输出X是第几小的数。
query3 X:找到当前序列中第X小的数是几。
然后输出的是3种query的和。
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <iostream>#include <vector>#include <map>#include <set>#include <queue>#include <ctime>using namespace std;typedef long long ll;typedef pair<int,int> pii;#define pb push_back#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define calm (l+r)>>1const int INF=1e9+7;const int maxn=100010;struct Data{ int t; int l,r,x;}input[220000];struct node{ int l,r,sum;}tree[maxn*20];int n,tot,rt[maxn];vector<int> v;inline int getid(int x){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}void readinput(){ char op[10]; for(int i=0;i<n;i++){ scanf("%s",op); if(op[0]=='I'){ int x;scanf("%d",&x); input[i].t=0; input[i].x=x; v.pb(x); } else if(op[6]=='1'){ int a,b,c;scanf("%d%d%d",&a,&b,&c); input[i].t=1; input[i].l=a;input[i].r=b;input[i].x=c; } else if(op[6]=='2'){ int x;scanf("%d",&x); input[i].t=2; input[i].x=x; } else{ int x;scanf("%d",&x); input[i].t=3; input[i].x=x; } }}void build(int l,int r,int &x){ x=++tot; tree[x].sum=0; if(l==r)return; int m=calm; build(l,m,tree[x].l); build(m+1,r,tree[x].r);}void update(int l,int r,int &x,int y,int k){ x=++tot; tree[x]=tree[y];tree[x].sum++; if(l==r)return; int m=calm; if(k<=m)update(l,m,tree[x].l,tree[y].l,k); else update(m+1,r,tree[x].r,tree[y].r,k);}int query1(int l,int r,int x,int y,int k){ if(l==r)return l; int m=calm; int sum=tree[tree[y].l].sum-tree[tree[x].l].sum; if(k<=sum)return query1(l,m,tree[x].l,tree[y].l,k); else return query1(m+1,r,tree[x].r,tree[y].r,k-sum);}int query2(int l,int r,int x,int k){ //printf("%d %d %d\n",l,r,k); if(l==r)return 1; int m=calm; if(k<=m)return query2(l,m,tree[x].l,k); else{ int sum=tree[tree[x].l].sum; return sum+query2(m+1,r,tree[x].r,k); }}int query3(int l,int r,int x,int k){ if(l==r)return l; int m=calm; int sum=tree[tree[x].l].sum; if(sum>=k)return query3(l,m,tree[x].l,k); else return query3(m+1,r,tree[x].r,k-sum);}int main(){ //freopen("D://input.txt","r",stdin); int kase=1; while(scanf("%d",&n)!=EOF){ v.clear();tot=0; ll ans1=0,ans2=0,ans3=0; readinput(); sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end()); int cnt=v.size(); build(1,cnt,rt[0]); int now=1; for(int i=0;i<n;i++){ if(input[i].t==0){ update(1,cnt,rt[now],rt[now-1],getid(input[i].x)); now++; } else if(input[i].t==1){ int l=input[i].l,r=input[i].r,x=input[i].x; ans1+=v[query1(1,cnt,rt[l-1],rt[r],x)-1]; } else if(input[i].t==2){ ans2+=query2(1,cnt,rt[now-1],getid(input[i].x)); } else if(input[i].t==3){ ans3+=v[query3(1,cnt,rt[now-1],input[i].x)-1]; } } printf("Case %d:\n",kase++); printf("%I64d\n%I64d\n%I64d\n",ans1,ans2,ans3); } return 0;}
0 0
- HDU3727 Jewel(主席树)
- HDU3727 Jewel (主席树)
- hdu3727 Jewel(划分树)
- HDU3727 Jewel
- HDU 3727 Jewel 主席树
- HDU 3727 Jewel 主席树
- hdu 3727 Jewel(主席树)
- HDU 3727 Jewel 简单主席树
- HDU 3727Jewel 主席树简单题
- hdu 3727 Jewel(主席树学习第四弹)
- uva11996 - Jewel Magic 伸展树
- 划分树(2010天津现场赛)hdu3727
- 主席、树、主席树!
- UVa 11996 Jewel Magic 伸展树
- HDU 3727 Jewel(划分树 + 二分)
- UVA 11996 Jewel Magic(伸展树)
- 主席树
- 主席树
- 哈理工OJ 1029 Function Run Fun(记忆思想)
- 剑指offer(二十八)之丑数
- jquery中Callbacks对象的实现
- ubuntu16.04为firefox添加pepperflash插件
- 构建高性能 ASP.NET应用的12点建
- HDU3727 Jewel(主席树)
- linux awk命令详解
- MySQL入门——修改数据表2:往指定的表中添加多列数据(字段)
- 漂亮的servlet-2,后台记录
- Swift-构造过程(Initialization)(十二)
- THE TOWER OF HANOI
- SQL SERVER 对权限的授予GRANT、拒绝DENY、收回REVOKE
- OOM原因和解决方案
- nyoj 1092数字分割(模拟)