zoukankan      html  css  js  c++  java
  • P1533 可怜的狗狗

    http://www.luogu.org/problem/show?pid=1533

    题目背景

    小卡由于公务需要出差,将新家中的狗狗们托付给朋友嘉嘉,但是嘉嘉是一个很懒的人,他才没那么多时间帮小卡喂狗狗。

    题目描述

    小卡家有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漂亮的狗的漂亮值。

    输出格式:

    M行,每行一个整数,表示每一次喂的那只狗漂亮值为多少。

    输入输出样例

    输入样例#1:
    7 2
    1 5 2 6 3 7 4
    1 5 3
    2 7 1
    
    输出样例#1:
    3
    2

    以前写的暴力60

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 1000000
    using namespace std;
    int n,m;
    char a2[300010];
    int a[300010],a1[300010];
    int x,y,k;
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            cin>>a1[i];
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&k);
            memset(a,maxn,sizeof(a));
            for(int i=1;i<=n;i++)
                a[i]=a1[i];
            sort(a+x,a+y+1);
            printf("%d
    ",a[k+x-1]);
        }
        return 0;
    }

    正解是什么,南城说是主席树

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int M=3e5+1000;
    const int N=M*25;
    int tot,sum[N],ls[N],rs[N],T[M],san[M],num[M];
    int n,m;
    void build(int &rt,int l,int r){
        rt=++tot;
        if(l==r) return ;
        int mid=l+r>>1;
        build(ls[rt],l,mid);
        build(rs[rt],mid+1,r);
    }
    void updata(int &rt,int last,int l,int r,int p){
        rt=++tot;
        ls[rt]=ls[last];
        rs[rt]=rs[last];
        sum[rt]=sum[last]+1;
        if(l==r) return ;
        int mid=l+r>>1;
        p<=mid?updata(ls[rt],ls[last],l,mid,p):updata(rs[rt],rs[last],mid+1,r,p);
    }
    int query(int l,int r,int x,int y,int k){
        if(l==r) return l;
        int mid=l+r>>1;
        int cnt=sum[ls[y]]-sum[ls[x]];
        k<=cnt?query(l,mid,ls[x],ls[y],k):query(mid+1,r,rs[x],rs[y],k-cnt);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) 
        {
            int a;
            scanf("%d",&a);
            san[i]=num[i]=a;
        }
        stable_sort(san+1,san+n+1);
        int cnt=unique(san+1,san+n+1)-(san+1);
        for(int i=1;i<=n;i++) num[i]=lower_bound(san+1,san+cnt+1,num[i])-san;
        build(T[0],1,cnt);
        for(int i=1;i<=n;i++) updata(T[i],T[i-1],1,cnt,num[i]);
        for(int i=1;i<=m;i++){
            int x,y,k;
            scanf("%d%d%d",&x,&y,&k);
            int id=query(1,cnt,T[x-1],T[y],k);
            printf("%d
    ",san[id]);
        }
        return 0;
    }
  • 相关阅读:
    [C/C++开发] Clion利用Docker开发和调试PHP扩展
    [C/C++开发] Clion利用Docker开发和调试PHP内核
    [C/C++开发] Clion利用Docker开发和调试Linux C/C++程序
    [Docker] 使用ubuntu涉及时区问题
    Oracle 导入 SQL 文件
    转载
    微信小程序
    微信小程序-点击复制功能
    服务器端基础概念
    VSCode 同步设置插件
  • 原文地址:https://www.cnblogs.com/xiaoningmeng/p/5931312.html
Copyright © 2011-2022 走看看