2017西安交大ACM小学期数据结构 [树状数组]

Problem C

发布时间: 2017年6月28日 11:38   最后更新: 2017年6月28日 16:38   时间限制: 1000ms   内存限制: 32M

给定一个长度为 n 的序列 a1 a2 , ...,  an , 其中 ai[1,10]

给出 q 个操作, 操作分为两种

对于形如 1   x   y 的操作, 将 ax 改为 y , 满足 1xn 1y10

对于形如 2   x   y   z 的操作, 输出下标介于 [x,y] 之间的元素中, 值为 z 的元素个数, 满足 1xyn 1z10

9×104n105 9×104q105

第一行两个整数 n q , 意义如上所述。
接下来 q 行, 每行第一个数为 opt , 如果 opt=1 , 后面紧跟两个数, 意义如上所述; 如果 opt=2 , 后面紧跟三个数, 意义如上所述。

对于每个操作 3 , 输出答案, 一行一个。

  复制
8 3
3 1 4 1 5 9 2 6
2 1 8 2
1 2 2
2 1 8 2
1
2

非常简单的一道题目,开10个树状数组。

bitree[z]含义分别是值为z的位置分布的树状数组。

当把数字a[x]变成y的时候,要做两件事情

第一件:消除旧值的影响

add(a[x],x,-1);

第二件

a[x] = y

add(a[x],x,1)

增加对新的数的影响

查询区间[x,y]等于z的数的个数时候

直接在z对应的树状数组里求部分和就OK了

是不是非常简单


#include <cstdio>
const int MAX = 1e5+7;
int a[MAX];
int in[11][MAX];
int n,q;
inline int lowbit(int x){
	return x&(-x);
}
void add(int id,int pos,int val){
	while(pos <= n){
		in[id][pos] += val;
		pos += lowbit(pos);
	}
}
int getsum(int id,int pos){
	int res = 0;
	while(pos){
		res += in[id][pos];
		pos -= lowbit(pos);
	}
	return res;
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i = 1;i <= n;i++){
		scanf("%d",&a[i]);
		add(a[i],i,1);
	}
	while(q--){
		int opt;scanf("%d",&opt);
		if(opt == 1){
			int x,y;
			scanf("%d%d",&x,&y);
			add(a[x],x,-1);
			a[x] = y;
			add(a[x],x,1);
		}
		else {
			int x,y,z;
			scanf("%d%d%d",&x,&y,&z);
			printf("%d\n",getsum(z,y) - getsum(z,x-1));
		}
	}
	
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值