【poj2104】K-th Number 归并树

来源:互联网 发布:淘宝延时喷剂是真的吗 编辑:程序博客网 时间:2024/06/13 23:08

说起来这是第二次A这个题了23333
第一次是分块,戳这里

归并树比分块打起来爽,速度还快,简直好评

思想:线段树套数组【雾。线段树每个节点保存它所表示的区间的有序数字排列。实现就是在归并排序的过程中保存归并排序的过程。蛮好打的。

并且调试什么的也没出什么大问题别忘了手动读入,别忘了读负数,归并排序的tmp数组不要menset(会T)(所以我直接没用tmp数组)

代码:

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<vector>using namespace std;const int size=200010;struct segment{    int l,r;    vector<int> num;}tree[size*4];int num[size];void merge(int p){    int pl=0,pr=0,pp=0;    int lz=tree[p<<1].num.size(),rz=tree[p<<1|1].num.size();    while(pl<lz||pr<rz)    {        if(pr>=rz|| ( pl<lz&&tree[p<<1].num[pl]<=tree[p<<1|1].num[pr] ) )            tree[p].num.push_back(tree[p<<1].num[pl++]);        else             tree[p].num.push_back(tree[p<<1|1].num[pr++]);    }}void build(int p,int l,int r){    tree[p].l=l;    tree[p].r=r;    if(l==r)    {        tree[p].num.push_back(num[l]);        return ;    }    int mid=(l+r)>>1;    build(p<<1,l,mid);    build(p<<1|1,mid+1,r);    merge(p);}int n,m;int ask(int p,int l,int r,int d){    if(l<=tree[p].l&&tree[p].r<=r)    {        return lower_bound(tree[p].num.begin(),tree[p].num.end(),d)-tree[p].num.begin();    }    int mid=(tree[p].l+tree[p].r)>>1;    int ans=0;    if(l<=mid) ans+=ask(p<<1,l,r,d);     if(mid<r) ans+=ask(p<<1|1,l,r,d);     return ans;}int div(int l,int r,int k){    int ll=0,rr=n+1;    while(rr-ll>1)    {        int mid=(ll+rr)>>1,tmp;        if(( tmp=ask(1,l,r,num[mid]) )>=k) rr=mid;        else ll=mid;      //  cout<<num[mid]<<" "<<tmp<<endl;    }    return num[ll];}void scan(int &n){    n=0;    int flag=1;    char a=getchar();    while(a>'9'||a<'0') {if(a=='-') flag=-1;a=getchar();}    while(a<='9'&&a>='0') n=n*10+a-'0',a=getchar();    n*=flag;}int main(){//  freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);          scan(n),scan(m);    for(int i=1;i<=n;i++)    {        scan(num[i]);    }    build(1,1,n);    sort(num+1,num+1+n);    while(m--)    {        int l,r,k;        scan(l),scan(r),scan(k);        printf("%d\n",div(l,r,k));    }    return 0;}
0 0
原创粉丝点击