题意:
思路:
主席树模板题,其实权值线段树也行,练练板子熟练度了
每次Insert就是新开一颗树,区间第k大和总体第k大就是正常的静态主席树操作,查询排名要注意,是包含那个数的
错误及反思:
代码:
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
#define lson l,m
#define rson m+1,r
const int N = 100100;
int sum[30*N],ls[N*30],rs[N*30],root[N],cnt,que,Case=1,tot;
long long q1,q2,q3;
vector<int> v;
struct Q{
char k; int l,r,d;
}q[35100*3+N];
int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
void init(){
cnt=0; v.clear();
tot=1; q1=0;
q2=0; q3=0;
v.push_back(0);
}
int build(int l,int r){
int rt=++cnt;
ls[rt]=rt; rs[rt]=rt; sum[rt]=0;
if(l==r) return rt;
int m=l+r>>1;
ls[rt]=build(lson); rs[rt]=build(rson);
return rt;
}
int update(int pre,int v,int l,int r){
int rt=++cnt;
ls[rt]=ls[pre]; rs[rt]=rs[pre]; sum[rt]=sum[pre]+1;
if(l==r) return rt;
int m=l+r>>1;
if(m>=v) ls[rt]=update(ls[pre],v,lson);
else rs[rt]=update(rs[pre],v,rson);
return rt;
}
int query(int lr,int rr,int k,int l,int r){
if(l==r) return r;
int tmp=sum[ls[rr]]-sum[ls[lr]],m=l+r>>1;
if(tmp>=k) return query(ls[lr],ls[rr],k,lson);
return query(rs[lr],rs[rr],k-tmp,rson);
}
int querysum(int p,int v,int l,int r){
if(l==r) return sum[p];
int m=l+r>>1;
if(m>=v) return querysum(ls[p],v,lson);
return sum[ls[p]]+querysum(rs[p],v,rson);
}
int main(){
while(scanf("%d",&que)!=EOF){
init();
for(int i=1;i<=que;i++){
char ta[10]; scanf("%s",ta);
if(ta[0]=='I'){
q[i].k=ta[0]; scanf("%d",&q[i].d);
v.push_back(q[i].d);
}
else if(ta[0]=='Q'&&ta[6]=='1'){
q[i].k='1'; scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].d);
}
else if(ta[0]=='Q'&&ta[6]=='2'){
q[i].k='2'; scanf("%d",&q[i].d);
}
else if(ta[0]=='Q'&&ta[6]=='3'){
q[i].k='3'; scanf("%d",&q[i].d);
}
}
sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
root[0]=build(1,v.size());
printf("Case %d:\n",Case++);
for(int i=1;i<=que;i++){
if(q[i].k=='I') root[tot]=update(root[tot-1],getid(q[i].d),1,v.size()),tot++;
else if(q[i].k=='1'){
q1+=v[query(root[q[i].l-1],root[q[i].r],q[i].d,1,v.size())-1];
}
else if(q[i].k=='2'){
q2+=querysum(root[tot-1],getid(q[i].d),1,v.size());
}
else{
q3+=v[query(root[0],root[tot-1],q[i].d,1,v.size())-1];
}
}
printf("%I64d\n%I64d\n%I64d\n",q1,q2,q3);
}
}