【SSL 1502】校门外的树【树状数组】

校门外的树

Time Limit:10000MS Memory Limit:65536K
Case Time Limit:1000MS

Description

校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……
如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:
K=1,读入l,r表示在l~r之间种上的一种树
K=2,读入l,r表示询问l~r之间能见到多少种树
(l,r>0)

Input

第一行n,m表示道路总长为n,共有m个操作
接下来m行为m个操作

Output

对于每个k=2输出一个答案

Sample Input

5 4
1 1 3
2 2 5
1 2 4
2 3 5

Sample Output

1
2

分析:

e m m m m m … … emmmmm…… emmmmm还是模板题
1 x 1 x 1x修改权值 2 x 2 x 2x区间和 A p p l e T r e e Apple Tree AppleTree的操作差不多
这道题不用遍历树 所以较为 e a s y easy easy
但是要开两个树状数组 以及要分别写两个操作函数

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 500005
using namespace std;
int n,m,a[N],c[N],qwq;
int lowbit(int x)
{
    
    
	return x&(-x);
}
void update(int x)
{
    
    
	for(;x<=n;x+=lowbit(x))  //修改权值
	c[x]++;
}
int find(int x)
{
    
    
	int ans=0;
	for(;x;x-=lowbit(x))  //求和
		ans+=c[x];
	return ans;
}
void update2(int x)
{
    
    
	for(;x<=n;x+=lowbit(x))  //同理
	a[x]++;
}
int find2(int x)
{
    
    
	int ans=0;
	for(;x;x-=lowbit(x))  //同理开两个
		ans+=a[x];
	return ans;
}
int main(){
    
    
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
    
    
		int X,l,r;
		scanf("%d%d%d",&X,&l,&r);
		if(X==1){
    
      //判断操作
			update(l);update2(r+1);
		}else{
    
    
			printf("%d\n",find(r)-find2(l));  //区间和
		}
	}	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/dgssl_xhy/article/details/108072359