hdu 3727 Jewel (主席树)

题意:

思路:

     主席树模板题,其实权值线段树也行,练练板子熟练度了
     每次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);
    }
}

猜你喜欢

转载自blog.csdn.net/Roll_Keyboard/article/details/80582931