您的位置:首页 > 产品设计 > UI/UE

hdu 5204 Rikka with sequence && BestCoder Round #37

2015-04-13 13:40 435 查看


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,表示第二种事件。
1≤n≤105,1≤L≤R≤1018,1≤w≤109,保证L,R,k合法, 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();
            }
        }
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: