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