【MD-80】【hdu】Kth number

3 篇文章 0 订阅
1 篇文章 0 订阅

Kth number

Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 12220 Accepted Submission(s): 3709

Problem Description
Give you a sequence and ask you the kth big number of a inteval.

Input
The first line is the number of the test cases.
For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere.
The second line contains n integers, describe the sequence.
Each of following m lines contains three integers s, t, k.
[s, t] indicates the interval and k indicates the kth big number in interval [s, t]

Output
For each test case, output m lines. Each line contains the kth big number.

Sample Input
1
10 1
1 4 2 3 5 6 7 8 9 0
1 3 2

Sample Output
2

Source
HDU男生专场公开赛——赶在女生之前先过节(From WHU)

Recommend
zty | We have carefully selected several similar problems for you: 2660 2662 1166 1754 2667

题解

在主席生日后不久,我们就收到了主席树的作业

google翻译:给你一个序列,并问你第k个大数字的一个。
题意:从小到大排序后第k个数
SMG!!!
然后主席树对于每一个操作都会新开一棵值域线段树树,并把没有改变的结点连到前一棵树上去
这样算来空间复杂度O(n*logINF)
轰!
所以要离散化(喵喵喵)
于是变为O(nlogn)
ps:把多组数据去掉可以交poj2104

ac代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 100010
#define INF 2147483647
using namespace std;
int t[N*20],num,lc[N*20],rc[N*20],n,m,p,q,o,T,rt[N],b[N];
struct Node{
    int v,id;
}a[N];
bool cmp(Node p,Node q){
    return p.v<q.v;
}
void Insert(int& x,int y,int l,int r){
    x=++num;
    t[x]=t[y]+1;
    lc[x]=lc[y];
    rc[x]=rc[y];
    if(l==r)return ;
    int mid=(l+r)>>1;
    if(p<=mid)Insert(lc[x],lc[y],l,mid);
    else Insert(rc[x],rc[y],mid+1,r);
}
int Query(int x,int y,int l,int r,int k){
    if(l==r)return a[l].v;
    int mid=(l+r)>>1;
    int d=t[lc[x]]-t[lc[y]];
    if(k<=d)return Query(lc[x],lc[y],l,mid,k);
    else return Query(rc[x],rc[y],mid+1,r,k-d);
}
int main(){
    freopen("data.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        num=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i].v);
            a[i].id=i;
        }
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++)b[a[i].id]=i;
        for(int i=1;i<=n;i++){
            p=b[i];
            Insert(rt[i],rt[i-1],1,n);
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&p,&q,&o);
            printf("%d\n",Query(rt[q],rt[p-1],1,n,o));
        }
    }
}

对拍

#include<cstdio>
#include<iostream>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#define MOD 100010
using namespace std;
int n,a[MOD+10],m,p,q,T;
int main(){
    freopen("data.txt","w",stdout);
    srand((unsigned)time(NULL));
    T=n=rand()%MOD+1;
    printf("%d\n",T);
    while(T--){
        n=rand()%MOD+1;
        m=rand()%MOD+1;
        printf("%d %d\n",n,m);
        for(int i=1;i<=n;i++)a[i]=rand()%MOD+1;
        for(int i=1;i<=n;i++)printf("%d ",a[i]);
        printf("\n");
        for(int i=1;i<=m;i++){
            while((p=rand()%n+1)>(q=rand()%n+1));
            printf("%d %d %d\n",p,q,rand()%(q-p+1)+1);
        }
    }
}

暴力

sort大暴力

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define N 200010
using namespace std;
int a[N],n,m,p,q,o,b[N],T;
bool cmp(int p,int q){
    return p>q;
}
int main(){
    freopen("data.txt","r",stdin);
    freopen("2.txt","w",stdout);
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        memcpy(b,a,sizeof(a));
        for(int i=1;i<=m;i++){
            memcpy(b,a,sizeof(a));
            scanf("%d%d%d",&p,&q,&o);
            sort(b+p,b+q+1,cmp);
            printf("%d\n",b[p+o-1]);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值