题目链接
题目大意:
蚂蚁的等级是由蚂蚁的能力排名所决定的,现在给定每一种等级的数量
有两种操作: 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)