zoukankan      html  css  js  c++  java
  • vijos 1081 野生动物园 函数式线段树

    描述

    cjBBteam拥有一个很大的野生动物园。这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域都饲养着一头狮子。这些狮子从北到南编号为1,2,3,…,N。每头狮子都有一个觅食能力值Ai,Ai越小觅食能力越强。饲养员cmdButtons决定对狮子进行M次投喂,每次投喂都选择一个区间[I,J],从中选取觅食能力值第K强的狮子进行投喂。值得注意的是,cmdButtons不愿意对某些区域进行过多的投喂,他认为这样有悖公平。因此cmdButtons的投喂区间是互不包含的。你的任务就是算出每次投喂后,食物被哪头狮子吃掉了。

    格式

    输入格式

    输入第一行有两个数N和M。此后一行有N个数,从南到北描述狮子的觅食能力值。此后M行,每行描述一次投喂。第t+2的三个数I,J,K表示在第t次投喂中,cmdButtons选择了区间[I,J]内觅食能力值第K强的狮子进行投喂。

    输出格式

    输出有M行,每行一个整数。第i行的整数表示在第i次投喂中吃到食物的狮子的觅食能力值。

    样例1

    样例输入1[复制]

    7 2
    1 5 2 6 3 7 4
    1 5 3
    2 7 1

    样例输出1[复制]

    3
    2

    限制

    各个测试点2s

    题意:没有修改,区间查询第k大

    思路:裸的主席树。区间第K大及它的各类变种CLJ的《可持续化数据结构研究》分析地很详细了 orz

    /** @Date    : 2016-12-15-20.55
      * @Author  : Lweleth (SoungEarlf@gmail.com)
      * @Link    : https://github.com/
      * @Version :
      */
    #include<bits/stdc++.h>
    #define LL long long
    #define PII pair
    #define MP(x, y) make_pair((x),(y))
    #define fi first
    #define se second
    #define PB(x) push_back((x))
    #define MMG(x) memset((x), -1,sizeof(x))
    #define MMF(x) memset((x),0,sizeof(x))
    #define MMI(x) memset((x), INF, sizeof(x))
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    const int N = 1e5+20;
    const double eps = 1e-8;
    
    struct yuu
    {
        int a, b, sum;
        int l, r;
    }tt[N << 5];
    
    int n, m;
    int rt[N], a[N], ss[N];
    int  cnt;
    
    void build(int a, int b, int &p)
    {
        p = ++cnt;
        tt[p].a = a;
        tt[p].b = b;
        if(a == b)
            return ;
        int mid = (a + b) >> 1;
        build(a, mid, tt[p].l);
        build(mid + 1, b, tt[p].r);
    }
    
    void add(int pre, int &p, int pos)
    {
        p = ++cnt;
        tt[p].l = tt[pre].l;
        tt[p].r = tt[pre].r;
        tt[p].a = tt[pre].a;
        tt[p].b = tt[pre].b;
        tt[p].sum = tt[pre].sum + 1;
        int mid = (tt[pre].a + tt[pre].b) >> 1;
        if(tt[pre].a < tt[pre].b)
            if(pos <= mid)
                add(tt[pre].l, tt[p].l, pos);
            else add(tt[pre].r, tt[p].r, pos);
    }
    
    int query(int pre, int nw, int s)
    {
        if(tt[nw].a == tt[nw].b)
        {
        	 return ss[tt[nw].a];
        }
            
        int t = tt[tt[nw].l].sum - tt[tt[pre].l].sum;
       
        if(s <= t)
            return query(tt[pre].l, tt[nw].l, s);
        else
            return query(tt[pre].r, tt[nw].r, s - t);
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]), ss[i] = a[i];
        sort(ss + 1, ss + 1 + n);
        MMF(rt);
        cnt = 0;
        build(1, n, rt[0]);
        for(int i = 1; i <= n; i++)
        {
            int pos = lower_bound(ss + 1, ss + 1 + n, a[i]) - ss;
            add(rt[i - 1], rt[i], pos);
        }
        for(int i = 1; i <= m; i++)
        {
            int x, y, k;
            scanf("%d%d%d", &x, &y, &k);
            int ans = query(rt[x - 1], rt[y], k);
            printf("%d
    ", ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    linux fork函数与vfork函数,exit,_exit区别
    wait、waitpid 僵尸进程 孤儿进程
    storage size of ‘oldact’ isn’t known
    xpath选择器使用
    linux read和write函数
    Sql case when用法
    linux select
    sublime使用
    notepad++使用技巧及插件汇总
    jQuery Ajax 实例 具体介绍$.ajax、$.post、$.get的使用
  • 原文地址:https://www.cnblogs.com/Yumesenya/p/6219552.html
Copyright © 2011-2022 走看看