zoj 3279 ants

题目链接

题目大意:

蚂蚁的等级是由蚂蚁的能力排名所决定的,现在给定每一种等级的数量

有两种操作:   p a b 表示,将等级为a的蚂蚁的数量改成b

                           q a 表示,查询能力排名为a的蚂蚁所在的等级


样例解释:

3
1 2 3
3
q 2
p 1 2
q 2
一开始:   lever[1] = 1, lever[2] = 2, lever[3] = 3

"q 2"后:   查询能力排名为2的蚂蚁所在的lever, 很明显等级为1的只有1个, 也就是排名为1的在lever[1], 那么 排名为2的就肯定在lever[2]了

"p 1 2":    将等级为1的蚂蚁的数量改成2,既lever[1] = 2

"q 2"后:    lever[1] = 2, 那么排名为2的蚂蚁就只能在 lever[1]里面了

解题思路:

本题采用线段树维护一个区间[a,b]的和,该长度表示 sum(lever[i]) , a<=i<=b, 用tree[k]表示, k为区间[a,b]的编号

对于操作"q a ":

              设当前所在区间的编号为k, 则其左儿子lson = k*2,  右儿子rson = k*2+1

              如果,    a<=tree[lson], 则递归的查询左儿子,且a不变

              否则,    递归进入右儿子, 但是此时  a = a-tree[lson],

对于操作"p a b“:

             这个应该很简单,就是线段树的 单点 修改操作


根据样例建立如下线段树:

“q 2”操作:

"p 1 2" 操作:

By the sway: poj 2182是本题相似,只是其没有修改操作,只有查询操作,比本题要容易一点,有兴趣的可以看poj2182题解

程序代码1:

const int maxN = 100005;
int tree[3*maxN];
int n,k,level[maxN];
void buildTree(int lb, int ub, int k)
{
    tree[k] = 0;
    if(lb == ub)    return;
    int mid = (lb+ub)/2;
    buildTree(lb, mid, k*2);
    buildTree(mid+1, ub, k*2+1);
}
void update(int pos, int x, int lb, int ub, int k)
{
    if(lb == ub){
        tree[k] = x;
    }else{
        int mid = (lb+ub)/2;
        if(pos<=mid) update(pos,x,lb,mid,k*2);
        else update(pos,x,mid+1,ub,k*2+1);
        tree[k] = tree[k*2] + tree[k*2+1];
    }
}
int query(int pos, int lb, int ub, int k)
{
    if(lb == ub){
        return lb;
    }else{
        int mid = (lb+ub)/2;
        if(pos<=tree[k*2]) return query(pos,lb,mid,k*2);
        else    return query(pos-tree[k*2],mid+1,ub,k*2+1);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    char q[3];
    int a,b;
    while(scanf("%d",&n)!=EOF){
        memset(level,0,sizeof(level));
        memset(tree,0,sizeof(tree));
        buildTree(1,n,1);
        for(int i=1;i<=n;i++){
            scanf("%d",&level[i]);
            update(i,level[i],1,n,1);
        }
        scanf("%d",&k);
        while(k--){
            scanf("%s%d",q,&a);
            if(q[0]=='q'){
                printf("%d\n",query(a,1,n,1));
            }else{
                scanf("%d",&b);
                update(a,b,1,n,1);
            }
        }
    }
    return 0;
}

程序代码2: 我用python提交,但是怎么修改输入输出都是Non-Zero-Exit, 不知道什么原因,  看以后学到python文件后能不能解决

import sys   
maxN = 100005
n = 0
k = 0
tree = [0 for i in xrange(4*maxN)]

def buildTree(l, r, k):
    tree[k] = 0
    if l == r:
        return
    else:
        mid = (l+r)/2
        buildTree(l, mid, k*2)
        buildTree(mid+1, r, k*2+1)
        
def update(a, b, l, r, k):
    if l == r:
        tree[k] = b
    else:
        mid = (l+r)/2
        if a<=mid:
            update(a, b, l, mid, k*2)
        else:
            update(a, b, mid+1, r, k*2+1)
        tree[k] = tree[k*2] + tree[k*2+1]

def query(a, l ,r, k):
    if l == r:
        return l
    else:
        mid = (l+r)/2
        if a<= tree[k*2]:
            return query(a, l, mid, k*2)
        else:
            return query(a-tree[k*2], mid+1, r, k*2+1)
        
line = raw_input()
while line:
    n = int(line.split()[0])
    lever = map(int, raw_input().split())
    k = int(raw_input().split()[0])
    buildTree(1,n,1)
    for i in xrange(n):
        update(i+1, lever[i], 1,n,1)
            
    while k>0:
        question = raw_input()
        if question[0]=='p':
            question = question.strip('p ')
            a,b = map(int, question.split())
            update(a,b,1,n,1)
        else:
            question = question.strip('q ')
            a = int(question.split()[0])
            print query(a,1,n,1)
        k-=1
    line = raw_input()
sys.exit(0)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值