BC #37 / hdu 5204 Rikka with sequence · 思维

题解

通过观察发现,
每执行一次 1 w,原先的数据下标变为原来的2倍,整个区间的数据个数变为原来的两倍
即第i次操作,整个区间的个数增加 2 i 2^i

已知区间最大 1 0 18 10^{18} ,最多含有59个不同的数,
59 - 1,152,921,504,606,846,974
60 - 2,305,843,009,213,693,950

每执行一次 2 l r k,对于新增加进来的w而言,[1,r] 内含有 r 2 \cfrac{r}{2} 个,[1,l-1] 内含有 l 1 2 \cfrac{l-1}{2} 个,
同理倒推上上次新增的w’,[1,r] 内含有 1 2 r 2 \cfrac{1}{2}*\cfrac{r}{2} 个,[1,l-1] 内含有 1 2 l 1 2 \cfrac{1}{2}*\cfrac{l-1}{2}个

因为最多将近60个不同的数字,操作次数n只有 1 0 5 10^5 ,所以,直接sort查第k大

注意一下区间端点的奇偶性引起的数值的变化


在这里插入图片描述


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
struct node {
    ll x,num;
}b[N];
bool cmp(node a,node b){
    return a.x<b.x;
}
ll a[N];
int tot=0;
ll l,r,k,w;
int main(){
    ios::sync_with_stdio(0);
    
    int T;
    cin>>T;
    for (int cs = 1,op; cs <= T; ++cs) {
        cin>>op;
        if(op==1){
            cin>>w;
            a[++tot]=w;
        }else{
            cin>>l>>r>>k;
            int cnt=0;
            for (int i = tot; i ; --i) {
                b[++cnt]={a[i],(r+1)/2-l/2};// [1,r] (1+r)/2
                /*
                    b[++cnt].x=a[i];
                    b[cnt].num=(r+1)/2-l/2;
                */
                r=r/2;
                l=(l+1)/2;
                if(l>r)break;//注意这里 r会变成0 但是l最小1 超出范围就没必要了
            }
            sort(b+1,b+1+cnt,cmp);
            for (int i = 1; i <= cnt; ++i) {
                k-=b[i].num;
                if(k<=0){
                    cout<<b[i].x<<endl;
                    break;
                }
            }
        }
    }
    return 0;
}
发布了34 篇原创文章 · 获赞 0 · 访问量 953

猜你喜欢

转载自blog.csdn.net/Yubing792289314/article/details/104210455
今日推荐