0
点赞
收藏
分享

微信扫一扫

hdu 5204(枚举+找规律)

拾杨梅记 2023-05-29 阅读 29


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;
}




举报

相关推荐

0 条评论