To_Heart—题解——VijosP1448 校门外的树

题目链接

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

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

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

样例1
样例输入1
5 4
1 1 3
2 2 5
1 2 4
2 3 5
样例输出1
1
2

Let us 分析一下样例:
首先,
有五个坑可以装树:

x            x             x            x            x

然后,我们执行第一个操作::在1~3号坑种树一;

(x            x             x)           x            x

括号括住的内容就是第一次种树的范围;
接下来我们进行第二次操作,输出2~5号坑,直接输出1,就不需要演示了。。。
第三次,输入,这次是在2~4里面种树(为了方便,我们把第二次输入表示成中括号):

(x          [ x             x)           x]           x

然后我们再来第四步:
输出3~5号坑:很容易发现,这几个坑里有两种树;
让后我们神奇的发现:
所谓l~r号坑中的树,其实就是在坑中不同括号的数量;
那么我们只需要写一个统计的代码即可:

#include <cstdio>
int a[50005],n,m;
long long bit[50005][2]; 

int Lowbit(int x){
	return x&(-x);
}

void HHup(int x,int k,int f){
	for(int i=x;i<=n;i+=Lowbit(i))
		bit[i][f]+=k;
	return ;
}

long long HHsum(int x1,int f){
	long long ans=0;
	for(int i=x1;i>=1;i-=Lowbit(i)){
		ans+=bit[i][f];
	}
	return ans;
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int pd;
		scanf("%d",&pd);
		if(pd==1){
			int l,r;
			scanf("%d%d",&l,&r);
			HHup(l,1,0);
			HHup(r,1,1);
		}
		else{
			int l,r;
			scanf("%d%d",&l,&r);
			long long ans1=HHsum(r,0);
			long long ans2=HHsum(l-1,1);
			printf("%lld\n",ans1-ans2);
		}
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值