Rikka with sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:
Yuta have a sequence. Because the sequence is very self-willed(RenXing), at first the sequence is empty. And then Yuta do n operations on this sequence, each operation is either of these two types:
1.Add a number w into each gap of the sequence. For example if w=3 and the sequence before is “2 4”, it will be changed to “3 2 3 4 3”.
**after the first operation of the first type, there is only one number in the sequence**
2.Query the kth small number in the subsequence [L,R]. For example if k=2, L=2, R=4 and the sequence is “3 2 3 4 2”, the answer will be 3.
Yuta wants Rikka to tell him the answer of each query.
It is too difficult for Rikka. Can you help her?
Input
n(n≤100000). Each of the following
n lines describes an operation: if it is “1 w” it will be the first type. Otherwise if it is “2 L R k”, it will be the second type.
(1≤w≤109,L≤R≤1018)
R will not be larger than the length of the sequence
Output
For each query operation, output one number – the answer.
Sample Input
6 1 3 1 1 2 2 3 2 1 2 2 3 5 2 2 1 4 4
Sample Output
3 2 3
规律:
对于1到L区间。前一个1操作产生的数 出现 (L+1)/2 次,然后再前一个出现 (L-(L+1)/2+1)/2次类推。每次 都会 折半,所以最多出现60个数。
所以先把1到(L-1)区间 中 出现的数 -1, 然后把1到R 区间中出现的数 +1,然后排序下这60个数,数到第k个就可以了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100005;
struct Node
{
int num;
LL bit;
bool operator < (const Node rhs) const
{
return num < rhs.num;
}
}tnum[maxn];
int num[maxn];
LL bit[70];
void calc(LL pos,int x)
{
int i = 1; //前面的第i个数
while(pos)
{
bit[i] += x * (pos + 1) / 2; //bit[i]表示在该区间内,前面的第i个数的个数
pos -= (pos + 1) / 2;
i++;
}
}
int main()
{
int n,len,op;
while(scanf("%d",&n)!=EOF)
{
len = 1;
while(n--)
{
scanf("%d",&op);
if(op & 1)
scanf("%d",&num[len++]);
else
{
LL l,r,k;
scanf("%lld%lld%lld",&l,&r,&k);
memset(bit,0,sizeof(bit));
calc(r,1);
calc(l-1,-1);
for(int i = 1; i <= 65; i++)
{
tnum[i].bit = bit[i];
if(len - i > 0)
tnum[i].num = num[len - i];
}
sort(tnum+1,tnum+1+65);
for(int i = 1; i <= 65; i++)
{
k -= tnum[i].bit;
if(k <= 0)
{
printf("%d\n",tnum[i].num);
break;
}
}
}
}
}
return 0;
}