Description
有一个长度为n的初始序列a,下标从1到n。
现在你有两种操作,
1:下标为k的数加1
2:序列中第k小的数是多少?
Input
第一行两个数n,m.表示序列长度和操作次数。
第二行n个数,表述序列的初始值。
接下来m行,每行两个数x,k。x表示操作种类数,1代表第一种操作,2代表第二种操作。
1<=n<=2e5,1<=m<=1e7,0<=a[i]<=1e7,1<=x<=2,1<=k<=n.
Output
对每次询问,输出第k大的数的值。
Sample
Input
5 5 1 2 3 4 5 2 3 1 1 2 1 2 2 2 3
Output
3 2 2 3
这题超级卡时间
#include <iostream>
#include <bits/stdc++.h>
#include <string.h>
#include <math.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
int n[200010],m[200010],s[10100010][2];
int main()
{
int a,b,x,y,i;
scanf("%d%d",&a,&b);
for(i=1; i<=a; i++)
{
scanf("%d",&n[i]);
m[i]=n[i];
}
sort(n+1,n+a+1);
for(i=0;i<=a+1;i++)//必须这样初始化,如果用memset会爆
{
s[i][0]=-1;
s[i][1]=-1;
}
for(i=1; i<=a; i++)//不能用嵌套
{
if(n[i]!=n[i+1])
{
s[n[i]][1]=i;
}
if(n[i]!=n[i-1])
{
s[n[i]][0]=i;
}
}
while(b--)
{
scanf("%d%d",&x,&y);
if(x==1)
{
n[s[m[y]][1]]++;
m[y]++;
s[m[y]-1][1]--;
if(s[m[y]][0]==-1)
{
s[m[y]][0]=s[m[y]-1][1]+1;
s[m[y]][1]=s[m[y]-1][1]+1;
}
else
{
s[m[y]][0]=s[m[y]-1][1]+1;
}
}
else if(x==2)
{
printf("%d\n",n[y]);
}
}
return 0;
}