hdu 5204 Rikka with sequence && BestCoder Round #37

Rikka with sequence

 
 Accepts: 34
 
 Submissions: 144
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:
现在有一个序列,因为这个序列很任性,开始时空的。接下来发生了
   
   
    
    n
   
   个事件,每一个事件是以下两种之一:
1.勇太利用黑炎龙的力量在序列的开头、结尾以及每相邻两个元素之间都插入一个权值为
   
   
    
    w
   
   的元素。若第一步执行事件一,执行后数列仅有一个数字w.
2.勇太想要六花告诉他第
   
   
    
    L
   
   个元素到第
   
   
    
    R
   
   个中权值第
   
   
    
    k
   
   小的权值是多少。
当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
第一行一个正整数
   
   
    
    n
   
   。接下来
   
   
    
    n
   
   行每一行描述了一种操作:
1.如果输入格式是1 w,表示第一种事件。
2.如果输入格式是2 L R k,表示第二种事件。

   
   
    
    1n1051LR10181w109
   
   ,保证
   
   
    
    LRk
   
   合法, R不会超过当前序列长度。
输出描述
对于每一个第二类事件,输出一个数字表示答案。
输入样例
6
1 3
1 1
2 2 3 2
1 2
2 3 5 2
2 1 4 4
输出样例
3
2
3

分析:1.对于给定的r,l,找出有哪些对应的元素及个数便可

   2.找第k小用map就t了,改成排序就过了

总结:1.结合最近的校选比赛:对每一个数据范围进行仔细考虑,找到那些奇特范围的突破口

           2.就像这道题,区间长度最大可达到2的几万次方之多,而这里只有l,r 只到1e18;

   3.相对区间长度来说,区间包含的元素种类只有1e5,所以从元素种类下手就是一个很好的突破口


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,LL>pii;
#define MAXN 100005
#define MAXM 65
int num[MAXN],n,cnt,op,total;
LL k,l,r;
pii ma[MAXM];
void find_kth()
{
    sort(ma,ma + total);
    for(int i = 0;i < total;i++)
    {
        k -= ma[i].second;
        if(k <= 0)
        {
            printf("%d\n",ma[i].first);
            return;
        }
    }
}
void solve()
{
    l--;
    total = 0;
    for(int i = cnt;l != r;i--)
    {
        LL cur = (r - l + (r & 1)) >> 1;
        if(cur)
        {
            ma[total].second = cur;
            ma[total++].first = num[i];
        }
        r >>= 1;
        l >>= 1;
    }
    find_kth();
}
int main()
{
    while(scanf("%d",&n) != EOF)
    {
        cnt = 0;
        for(int i = 0;i < n;i++)
        {
            scanf("%d",&op);
            if(op == 1)scanf("%d",&num[++cnt]);
            else
            {
                scanf("%I64d%I64d%I64d",&l,&r,&k);
                solve();
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值