厦门1165 第K小数 树状数组 不重复数字
2010-08-28 22:32
197 查看
1165.第K小数
Time Limit: 1000 MS Memory Limit: 65536 K
Total Submissions: 467 (117 users) Accepted: 117 (66 users)
[ My Solution ]
Description
给定一个空的正整数集合S,然后再给定一组操作,这组操作共有三种
1. 添加某个正整数a到集合中,若a已经在S中则不需要重复加入
2. 从集合中删除某个整数a,若a不在S中则忽略该操作
3. 查询集合中的第k小数,若不存在第k小数则输出-1,否则输出第k小数
Input
第一行为正整数n(2<=n<=100000)分别表示操作的个数
接下来n行每行为两个数字表示一个操作。第一个数字为操作的编号,1表示添加操作,2表示删除操作,3表示查询操作,
第二个数字为要添加删除的正整数a(0<a<=100000)或要查询的第k小数k。
Output
对于每一个查询操作,若不存在第k小数则输出-1,否则输出第k小数
Sample Input
10
1 1
1 1
2 3
3 1
3 2
2 1
1 2
3 1
1 1
3 1
Sample Output
1
-1
2
1
Hint
输入输出巨大,如果您使用C/C++建议用scanf和printf输入输出。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int n=100000;
int c[n+1];
inline int lowbit(int x)
{
return x&(-x);
}
void update(int x,int val)
{
for(int i=x;i<=n;i+=lowbit(i))
{
c[i]+=val;
}
}
int getsum(int x)
{
int cnt=0;
for(int i=x;i>=1;i-=lowbit(i))
{
cnt+=c[i];
}
return cnt;
}
int binary_search(int l,int r,int goal)
{
if(l<r)
{
int mid=(l+r)>>1;
if(getsum(mid)==goal) return mid;
else if(getsum(mid)>goal) return binary_search(l,mid,goal);
else return binary_search(mid+1,r,goal);
}
return -1;
}
int main()
{
int ci;scanf("%d",&ci);
while(ci--)
{
int x,y;
scanf("%d%d",&x,&y);
if(x==1)
{
if((getsum(y)-getsum(y-1))==0)
{
update(y,1);
}
}
else if(x==2)
{
if((getsum(y)-getsum(y-1))==1)
{
update(y,-1);
}
}
else
{
int cnt=binary_search(1,n+1,y);
if(cnt==-1) printf("-1/n");
else
{
for(;cnt>=1&&getsum(cnt)==y;cnt--);cnt++;
printf("%d/n",cnt);
}
}
}
return 0;
}
/*
10
1 1
1 1
2 3
3 1
3 2
2 1
1 2
3 1
1 1
3 1
*/
程序员求签 http://6.kongzhidea.duapp.com/demos/kk/index.php/fun/pray
Time Limit: 1000 MS Memory Limit: 65536 K
Total Submissions: 467 (117 users) Accepted: 117 (66 users)
[ My Solution ]
Description
给定一个空的正整数集合S,然后再给定一组操作,这组操作共有三种
1. 添加某个正整数a到集合中,若a已经在S中则不需要重复加入
2. 从集合中删除某个整数a,若a不在S中则忽略该操作
3. 查询集合中的第k小数,若不存在第k小数则输出-1,否则输出第k小数
Input
第一行为正整数n(2<=n<=100000)分别表示操作的个数
接下来n行每行为两个数字表示一个操作。第一个数字为操作的编号,1表示添加操作,2表示删除操作,3表示查询操作,
第二个数字为要添加删除的正整数a(0<a<=100000)或要查询的第k小数k。
Output
对于每一个查询操作,若不存在第k小数则输出-1,否则输出第k小数
Sample Input
10
1 1
1 1
2 3
3 1
3 2
2 1
1 2
3 1
1 1
3 1
Sample Output
1
-1
2
1
Hint
输入输出巨大,如果您使用C/C++建议用scanf和printf输入输出。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int n=100000;
int c[n+1];
inline int lowbit(int x)
{
return x&(-x);
}
void update(int x,int val)
{
for(int i=x;i<=n;i+=lowbit(i))
{
c[i]+=val;
}
}
int getsum(int x)
{
int cnt=0;
for(int i=x;i>=1;i-=lowbit(i))
{
cnt+=c[i];
}
return cnt;
}
int binary_search(int l,int r,int goal)
{
if(l<r)
{
int mid=(l+r)>>1;
if(getsum(mid)==goal) return mid;
else if(getsum(mid)>goal) return binary_search(l,mid,goal);
else return binary_search(mid+1,r,goal);
}
return -1;
}
int main()
{
int ci;scanf("%d",&ci);
while(ci--)
{
int x,y;
scanf("%d%d",&x,&y);
if(x==1)
{
if((getsum(y)-getsum(y-1))==0)
{
update(y,1);
}
}
else if(x==2)
{
if((getsum(y)-getsum(y-1))==1)
{
update(y,-1);
}
}
else
{
int cnt=binary_search(1,n+1,y);
if(cnt==-1) printf("-1/n");
else
{
for(;cnt>=1&&getsum(cnt)==y;cnt--);cnt++;
printf("%d/n",cnt);
}
}
}
return 0;
}
/*
10
1 1
1 1
2 3
3 1
3 2
2 1
1 2
3 1
1 1
3 1
*/
程序员求签 http://6.kongzhidea.duapp.com/demos/kk/index.php/fun/pray
相关文章推荐
- HDU 2852 树状数组解决第K小数 附线段树解法
- HDU2852 大于a的第k小数-树状数组
- 树状数组求逆序对/ 兼板子 (有无重复数字都可)
- 寻找数组中的第K大的元素&找数组中重复数字
- 去除数组中的重复数字
- 作业-创建数组随机生成30个不重复数字进去-在随机出来5个-然后排序输出
- 数组中重复的数字
- 去除数组中的重复数字
- 【树状数组求第k小+并查集】POJ 2985
- 九度 1534 数组中第K小的数字
- 剑指offer--数组中重复的数字
- 剑指offer 面试题51 数组中重复的数字
- 数组中重复的数字
- 数组中第k小的数字
- LintCode: 删除排序数组中的重复数字
- lintcode--删除排序数组中的重复数字
- 数组中重复的数字
- java 实现递归查找数组中的重复数字
- 数组a[N],存放了1至N-1个数,其中某个数重复一次。写一个函数,找出被重复的数字.时间复杂度必须为o(N)函数原型:
- BZOJ 2738 子矩阵第k大 | 二维树状数组 整体二分 分治