PKU 2761 Feed the dogs

来源:互联网 发布:mysql 5.6.19.tar.gz 编辑:程序博客网 时间:2024/05/20 09:46
题目:http://poj.org/problem?id=2761题意:有n个数,给m个区间,求这m个区间的地K大值思路:裸划分树,与2104相同~~#include <stdio.h>#include <iostream>#include <algorithm>using namespace std;const int maxn=100000;int n, m, a, b, c;int sorted[maxn+10], array[40][maxn+10], num[40][maxn+10];void BuildTree(int v, int left, int right){    if (left==right) return;    int mid=(left+right)>>1;    int lchild=left, rchild=mid+1;    int isame=mid-left+1, same=0;    for (int i=left; i<=right; i++) if (array[v][i]<sorted[mid]) isame--;    for (int i=left; i<=right; i++)    {        if (i==left) num[v][i]=0;        else num[v][i]=num[v][i-1];        if (array[v][i]<sorted[mid])        {            num[v][i]++;            array[v+1][lchild++]=array[v][i];        }        else if (array[v][i]>sorted[mid]) array[v+1][rchild++]=array[v][i];        else        {            if (same<isame)            {                same++;                num[v][i]++;                array[v+1][lchild++]=array[v][i];            }            else array[v+1][rchild++]=array[v][i];        }    }    BuildTree(v+1, left, mid);    BuildTree(v+1, mid+1, right);}int Query(int l, int r, int k, int v, int left, int right){    if (left==right) return array[v][l];    int mid=(left+right)>>1;    int s, ss, b, bb;    if (l==left)    {        s=num[v][r];        ss=0;    }    else    {        s=num[v][r]-num[v][l-1];        ss=num[v][l-1];    }    if (s>=k)    {        l=left+ss;        r=left+ss+s-1;        return Query(l, r, k, v+1, left, mid);    }    else    {        b=l-left-ss;        bb=r-l-s+1;        l=mid+b+1;        r=mid+b+bb;        return Query(l, r, k-s, v+1, mid+1, right);    }}int main(){    //freopen("in.txt", "r", stdin);    while (scanf("%d %d", &n, &m)==2)    {        for (int i=1; i<=n; i++)        {            scanf("%d", &sorted[i]);            array[1][i]=sorted[i];        }        sort(sorted+1, sorted+1+n);        BuildTree(1, 1, n);        for (int i=0; i<m; i++)        {            scanf("%d %d %d", &a, &b, &c);            printf("%d\n", Query(a, b, c, 1, 1, n));        }    }    return 0;}
原创粉丝点击