洛谷2184 贪婪大陆(树状数组)

传送门

【题目分析】

考虑每次是在区间[l,r]中埋一种,所以记录每次的左右端点,查询一段区间[l,r]就是统计1~r中埋了多少雷,再减去1~l-1中埋完的雷(即右端点)即可。

所以用两个树状数组维护左右端点信息即可。(常数比线段树要小)

【代码~】

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
const int MOD=1e6;

int n,q;
int tr1[MAXN],tr2[MAXN];

int Read(){
	int i=0,f=1;
	char c;
	for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar());
	if(c=='-')
	  f=-1,c=getchar();
	for(;c>='0'&&c<='9';c=getchar())
	  i=(i<<3)+(i<<1)+c-'0';
	return i*f;
}

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

void update(int x,int y,int v){
	for(int i=x;i<=n;i+=lowbit(i))
	  tr1[i]+=v;
	for(int i=y;i<=n;i+=lowbit(i))
	  tr2[i]+=v;
}

int query(int x,int y){
	int ret=0;
	for(int i=y;i;i-=lowbit(i))
	  ret+=tr1[i];
	for(int i=x;i;i-=lowbit(i))
	  ret-=tr2[i];
	return ret;
}

int main(){
	n=Read(),q=Read();
	while(q--){
		int cz=Read(),l=Read(),r=Read();
		if(cz==1)
		  update(l,r,1);
		else
		  printf("%d\n",query(l-1,r));
	}
	return 0;
}

 

posted @ 2018-10-29 14:17  Ishtar~  阅读(121)  评论(0编辑  收藏  举报