您的位置:首页 > 其它

zoj 3279 ants 线段树+单点更新+查询下标

2017-02-26 12:48 357 查看
题目:

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


有不超过100000种leval  每个等级有一定数量的蚂蚁 蚂蚁总共不超过 2000000000(可以用int维护线段树) 

p a b 指 leval 为a的蚂蚁数量变成b 

q x 蚂蚁在leval排名中位列第x,求它的leval 

思路:

基础线段树,线段树数组维护蚂蚁数量,第一个操作为单点更新,第二个操作为从前向后查询返回满足条件的下标。

输入需要注意一下:

scanf("%c",&answer) 与 scanf(" %c",&answer),后者只是在%前多了个空格,似乎没有什么区别,但使用起来区别是很大的。
scanf()作单字符输入时规定只接收一个字符,但它却把回车符也作为字符对待的。这就造成程序中只有一个输入字符的scanf()语句时,问题还不大,但如果后面还跟着第二个scanf()字符输入语句,这个scanf()就把前面输入的回车符当作输入字符了。这就在输入逻辑上造成了混乱,达不到人们预期的愿望。
有了这个空格,这个空格就相当于要求输入一个空格,刚好把刚才的'\n'接收掉。之所以' '能接收'\n',是因为"%c...."中的空格是广义的,对‘\n'、'\t'都有效。而且实践证明,这个空格放在%c后面也不能达到目的。应当说,这也是比较巧妙的应用!

(参 : https://zhidao.baidu.com/question/392449587678951245.html)
当然,此处scanf(" %c",&c) + c==... 也可以用scanf("%s",c)  + c[0]=....替换

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<ctype.h>    //tower()
#include<set>
#include<map>
#include<iomanip>// cout<<setprecision(1)<<fixed<<a;
#include<vector>
#include<time.h>
#include<assert.h>  //assert
#include<cmath>
#include<algorithm>
#include<bitset>
#include<limits.h>
#include<stack>
#include<queue>
using namespace std;
const int maxn=100010;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1

int n,k,a,b;
int sum[maxn<<2];
char c;

void build(int l,int r,int rt){
if(l==r){
scanf("%d",&sum[rt]);
return ;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void update(int a,int b,int l,int r,int rt){
if(l==r){
sum[rt]=b;
return ;
}
int mid=(l+r)>>1;
if(a<=mid) update(a,b,lson);
else update(a,b,rson);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

int query(int va,int l,int r,int rt){
if(l==r) return l;
int mid=(l+r)>>1;
if(va<=sum[rt<<1])return query(va,lson);
else return query(va-sum[rt<<1],rson);
}

int main(){//160 MS 1848K
while(~scanf("%d",&n)){
build(1,n,1);
scanf("%d",&k);
while(k--){
scanf(" %c",&c);//注意输入需要多一个空格
if(c=='p'){
scanf("%d%d",&a,&b);
update(a,b,1,n,1);
}
else{
scanf("%d",&a);
printf("%d\n",query(a,1,n,1));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: