首页 > 其他 > 详细

P1553 可怜的狗狗(可持久化线段树)

时间:2020-08-03 23:43:40      阅读:91      评论:0      收藏:0      [点我收藏+]

小卡家有N只狗,由于品种、年龄不同,每一只狗都有一个不同的漂亮值。漂亮值与漂亮的程度成反比(漂亮值越低越漂亮),吃饭时,狗狗们会按顺序站成一排等着主人给食物。

可是嘉嘉真的很懒,他才不肯喂这么多狗呢,这多浪费时间啊,于是他每次就只给第i只到第j只狗中第k漂亮的狗狗喂食(好狠心的人啊)。而且为了保证某一只狗狗不会被喂太多次,他喂的每个区间(i,j)不互相包含。

第一行输入两个数n,m,你可以假设n<300001 并且 m<50001;m表示他喂了m次。

第二行n个整数,表示第i只狗的漂亮值为ai。

接下来m行,每行3个整数i,j,k表示这次喂食喂第i到第j只狗中第k漂亮的狗的漂亮值。

题解:

就是可持久化线段树...用平衡树套线段树会TLE。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=4e5+10;
int n,q,m,tot;
int a[maxn];
int t[maxn];
int T[maxn];
int lson[maxn*30],rson[maxn*30],c[maxn*30];
void init_hash () {
    for (int i=1;i<=n;i++) t[i]=a[i];
    sort(t+1,t+n+1);
    m=unique(t+1,t+n+1)-t-1;
}
int build (int l,int r) {
    int root=tot++;
    c[root]=0;
    if (l!=r) {
        int mid=(l+r)>>1;
        lson[root]=build(l,mid);
        rson[root]=build(mid+1,r);
    }
    return root;
}
int Hash (int x) {
    return lower_bound(t+1,t+m+1,x)-t;
}
int update (int root,int pos,int val) {
    int newroot=tot++,tmp=newroot;
    c[newroot]=c[root]+val;
    int l=1,r=m;
    while (l<r) {
        int mid=(l+r)>>1;
        if (pos<=mid) {
            lson[newroot]=tot++;
            rson[newroot]=rson[root];
            newroot=lson[newroot];
            root=lson[root];
            r=mid;
        }
        else {
            rson[newroot]=tot++;
            lson[newroot]=lson[root];
            newroot=rson[newroot];
            root=rson[root];
            l=mid+1;
        }
        c[newroot]=c[root]+val;
    }
    return tmp;
}
int query (int left_root,int right_root,int k) {
    int l=1,r=m;
    while (l<r) {
        int mid=(l+r)>>1;
        if (c[lson[left_root]]-c[lson[right_root]]>=k) {
            r=mid;
            left_root=lson[left_root];
            right_root=lson[right_root];
        }
        else {
            l=mid+1;
            k-=c[lson[left_root]]-c[lson[right_root]];
            left_root=rson[left_root];
            right_root=rson[right_root];
        }
    }
    return l;
}
int main () {
    while (~scanf("%d%d",&n,&q)) {
        tot=0;
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        init_hash();
        T[n+1]=build(1,m);
        for (int i=n;i;i--) {
            int pos=Hash(a[i]);
            T[i]=update(T[i+1],pos,1);
        }
        while (q--) {
            int l,r,k;
            scanf("%d%d%d",&l,&r,&k);
            printf("%d\n",t[query(T[l],T[r+1],k)]);
        }
    }
    return 0;
}

 

P1553 可怜的狗狗(可持久化线段树)

原文:https://www.cnblogs.com/zhanglichen/p/13429786.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!