HDU 5204 Rikka with sequence 思维.

来源:互联网 发布:淘宝网中老年女外套 编辑:程序博客网 时间:2024/06/16 00:35
HDU 5204
题意:初始序列为空,现在有n个操作.
操作1:将x插入到序列a的每两个数中间,例如{2,4} x=3 ->{3,2,3,4}.
操作2: 询问[L,R]的第k小元素?
n<=1e5,x<=1e9,L,R<=1e18.

初始0个 第一次加1个 第二次加2个 第三次加4个...
第i次插入操作加入2^i个x.[L,R]查询区间内最多60个数左右.


询问[L,R] 对于它上一个op1添加的x. x在[1,L]中出现L/2次,[1,R]出现R/2次 算出op1添加的数x 在[L,R]出现的次数即可.
经过op1后,原序列中每个数下标都变为原来的两倍.

x前一次op1添加的x',x'在[1,L]出现 L/2/2

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N=2e5+5;struct node{    ll x,num;}b[N];bool cmp(node a,node b){    return a.x<b.x;}int a[N];int main(){    int n,tot=0;    scanf("%d",&n);    while(n--)    {        int op;        ll x,l,r,k;        scanf("%d",&op);        if(op==1)            scanf("%lld",&x),a[++tot]=x;        else        {            scanf("%lld%lld%lld",&l,&r,&k);            int num=0;            for(int i=tot;i>=1;i--)            {                b[++num].x=a[i];                b[num].num=(r+1)/2-l/2;                r/=2,l=(l+1)/2;                if(l>r)                    break;            }            sort(b+1,b+1+num,cmp);            for(int i=1;i<=num;i++)            {                k-=b[i].num;                if(k<=0)                {                    printf("%lld\n",b[i].x);                    break;                }            }        }    }    return 0;}