1. 程式人生 > >洛谷2184 貪婪大陸(樹狀陣列)

洛谷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;
}