ZOJ - 3279 Ants

ZOJ - 3279 Ants

                        Time Limit: 2 Seconds      Memory Limit: 32768 KB

echo is a curious and clever girl, and she is addicted to the ants recently.

She knows that the ants are divided into many levels depends on ability, also, she finds the number of each level will change.

Now, she will give two kinds of operations as follow :

First, “p a b”, the number of ants in level a change to b.

Second, “q x”, it means if the ant’s ability is rank xth in all ants, what level will it in?

Input

There are multi-cases, and you should use EOF to check whether it is in the end of the input. The first line is an integer n, means the number of level. (1 <= n <= 100000). The second line follows n integers, the ith integer means the number in level i. The third line is an integer k, means the total number of operations. Then following k lines, each line will be “p a b” or “q x”, and 1 <= x <= total ants, 1 <= a <= n, 0 <= b. What’s more, the total number of ants won’t exceed 2000000000 in any time.

Output

Output each query in order, one query each line.

Sample Input

3
1 2 3
3
q 2
p 1 2
q 2
Sample Output

2
1

题目链接:ZOJ 3279

题目大意:有1~n等级的蚂蚁,两种操作,p,把a等级蚂蚁数目改成b。q,问排名第x的蚂蚁是属于第几个等级

题目思路:线段树

以下是代码:

#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
/* 说明: 1. rt、L、R都是从1开始计数; 2. 线段树的空间应当是原数组的四倍;(最小应该为,向上取到最近的二的次幂,再乘以2) 3. 每次调用build,query和update时,L和R应该是整个区间(1-N),一般写成query(1,1,N)。 */ 

#define lson rt<<1,L,M
#define rson rt<<1|1,M+1,R
#define maxn 100000 + 10
#define ll long long
ll sumv[maxn<<2];
ll level[maxn];
ll num[2][maxn];
void pushUp(ll rt) {
    sumv[rt] = sumv[rt<<1] + sumv[rt<<1|1];
}

void build(ll rt, ll L, ll R) {
    ll M = (L+R) >> 1;
    if (L == R) {
        sumv[rt] = level[L];
    } 
    else {
        build(lson);
        build(rson);
        pushUp(rt);
    }
}

//单点更新 
void update(ll p, ll add, ll rt, ll L, ll R) { //p代表要更新的点的位置
    ll M = (L+R) >> 1;
    if (L == R) {
        sumv[rt] = add; 
    } else {
        if (p <= M) update(p, add, lson);
        else update(p, add, rson);
        pushUp(rt);
    } 
}


int query(ll L, ll R, ll k, ll i)
{
    if (L == R) return L;
    ll M = (L + R) >> 1;
    if (k <= sumv[i * 2]) return query(L, M,k,i * 2);
    else return query(M + 1,R,k - sumv[i * 2],i * 2 + 1); 
}

int main(){
    ll n;
    while(scanf("%lld",&n) != EOF)
    {
        for (ll i = 1; i <= n; i++)
        {
            scanf("%lld",&level[i]);
        }
        ll k;
        scanf("%lld",&k);
        build(1,1,n);
        while(k--)
        {
            char ch;
            scanf("%*c%c",&ch);
            ll a,b;
            if (ch == 'p')
            {
                scanf("%lld%lld",&a,&b);
                update(a,b,1,1,n);
            }
            else
            {
                scanf("%lld",&a);
                ll ans = query(1,n,a,1);    
                printf("%lld\n",ans);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(线段树)