HDU3727 Jewel(主席树)
2016-05-20 21:46
232 查看
传送门: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的和。
这题还是挺需要细心的,算是主席树一个挺好的练手题了。
题意:输入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)>>1 const 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; }
相关文章推荐
- 习题 8-18 UVA - 1619 Feel Good 感觉不错 (容斥定理)
- 漂亮的servlet-2,后台记录
- ubuntu16.04为firefox添加pepperflash插件
- ThinkPHP表单操作(未加验证)
- sql盲注及其相关方法
- 构建高性能 ASP.NET应用的12点建
- 芯片新知识
- Java 设计模式 -- 职责链模式
- tomcat 设置CATALINA_PID, shutdown失败后,会kill pid
- Android之Bundle类
- TCP/IP中MSL详解
- 哈理工OJ 1029 Function Run Fun(记忆思想)
- clazz.isArray()
- win10下sourcetree使用密钥克隆仓库时提示一直在加载的解决办法
- python
- 为什么要设置Java环境变量(详解)
- poj 1061 青蛙的约会 (扩展欧几里得模板)
- NYOJ 954 N! (数学)
- 判断一个链表是否为回文结构
- 数组