传送门
题目大意:
有一群蚂蚁,每只蚂蚁有一个能力值,现在对这些蚂蚁分类,分为N组,最高的A1个为第一组,接着的A2个为第二组,依次类推。
现在有两种操作:
(1)修改操作:C i a,表示将Ai修改为a,也就是说第i组的蚂蚁数变成a;
(2)询问操作:q x,询问能力值排名第x的蚂蚁归哪一组。
要求对每个询问操作进行输出。
数据范围:
N<=105
思路:用树状数组维护一个A数组的前缀和,询问的时候二分查找最小的大于等于x的数,时间复杂度
O(N∗logN∗logN)
#include<cstdio>
#include<cstring>
#define MAXN 100005
int t[MAXN], n, a[MAXN], m, t1, t2, l, r, mid, tmp;
char s[5];
inline int lowbit(int x)
{
return x&-x;
}
void Upd(int x, int v)
{
for(; x <= n; x += lowbit(x))
t[x] += v;
}
int sum(int x)
{
int sum = 0;
for(; x > 0; x -= lowbit(x))
sum += t[x];
return sum;
}
int main()
{
while(~scanf("%d", &n))
{
memset(t, 0, sizeof t);
for(int i = 1; i <= n; i ++){
scanf("%d", a + i);
Upd(i, a[i]);
}
scanf("%d", &m);
for(int i = 1; i <= m; i ++)
{
scanf("%s", s);
if(s[0] == 'q')
{
l = 1, r = n;
scanf("%d", &t1);
while(l <= r)
{
mid = l + r >> 1;
if(sum(mid) < t1) l = mid + 1;
else r = mid - 1;
}
printf("%d\n",l);
}
else
{
scanf("%d%d", &t1, &t2);
Upd(t1, t2 - a[t1]);
a[t1] = t2;
}
}
}
return 0;
}