您的位置:首页 > 其它

HDU 2852

2016-07-08 19:30 323 查看
题意:建一个整数容器,容器有三种操作:1.加入成员 2.删除成员,无法删除则输出NOT FIND 3.输入n和k,输出在容器中的比n大的第k个成员

思路:有线段树和单调栈的做法,但用树状数组比较方便

刚开始学树状数组并不知道它支持删除跟查询第k个元素的功能,看了别人的博客才知道可以在数组中不保存元素和而是保存元素的序号,直接看代码比较好理解

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
//A B D E K L G
const int MAXN = 100010;
int p, m;
int str[MAXN], Hash[MAXN];
int lowbit(int x)
{
return x & (-x);
}
void add(int num, int d)
{
int i = num;
if (d == -1 && !Hash[num])
{
printf("No Elment!\n");
return;
}
Hash[num] += d;
while (i < MAXN)
{
str[i] += d;
i += lowbit(i);
}
}
int sum(int x)
{
int i = x, c=0;
while (i > 0)
{
c += str[i];
i -= lowbit(i);
}
return c;
}
void check(int num, int k)
{
int temp = sum(num);
int head = num;
int tail = MAXN;
int mid;
while (head <= tail)
{
mid = (head + tail) / 2;
int cnt = sum(mid);
if (Hash[mid] && cnt-temp >= k && cnt-temp < k + Hash[mid])
{
printf("%d\n", mid);
return;
}
else
{
if(cnt-temp<k)
{
head=mid+1;
}
else
{
tail=mid-1;
}
}
}
printf("Not Find!\n");
}
int main()
{
while (~scanf("%d", &m))
{
memset(Hash, 0, sizeof Hash);
memset(str, 0, sizeof str);
for (int i = 0; i < m; i++)
{
scanf("%d", &p);
int num;
if (p == 0)
{
scanf("%d", &num);
add(num, 1);
}
else if (p == 1)
{
scanf("%d", &num);
add(num, -1);
}
else
{
int k;
scanf("%d%d", &num, &k);
check(num,k);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: