BZOJ3343 教主的魔法(分块)

因为没有权限号所以挂洛谷链接

【题目分析】

发现很久没动过分块了,找几道题来做一做。。。。

分块好题,因为涉及区间加,那么开一个标记数组,类似于线段树的lazy标记。

询问区间大于等于k的数的个数,同一块内直接暴力统计,整块二分求解(二分永远最玄学啊。。。)

区间加,块内暴力加,整块就在标记数组上打标记即可。

【代码~】

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

int n,q;
int h[MAXN],hh[MAXN];
int l[MAXN],r[MAXN],sig[MAXN];
int siz,num,belong[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;
}

void px(int x){
	int a=l[x],b=r[x];
	for(int i=a;i<=b;++i)
	  hh[i]=h[i];
	sort(hh+a,hh+b+1);
}

void fk(){
	siz=sqrt(n);
	num=(n/siz)+(n%siz?1:0);
	for(int i=1;i<num;++i){
		l[i]=(i-1)*siz+1;
		r[i]=i*siz;
	}
	l[num]=r[num-1]+1;
	r[num]=n;
	for(int i=1;i<=n;++i)
	  belong[i]=((i-1)/siz)+1;
	for(int i=1;i<=num;++i)
	  px(i);
}

int calc(int x,int y){
	int a=l[x],b=r[x];
	while(a<=b){
		int mid=a+b>>1;
		if(hh[mid]<y)
		  a=mid+1;
		else
		  b=mid-1;
	}
	return r[x]-a+1;
}

void add(int x,int y,int k){
	if(belong[x]==belong[y]){
		if(sig[belong[x]]){
			for(int i=l[belong[x]];i<=r[belong[x]];++i)
			  h[i]+=sig[belong[x]];
		}
		sig[belong[x]]=0;
		for(int i=x;i<=y;++i)
		  h[i]+=k;
		px(belong[x]);
		return ;
	}
	for(int i=x;i<=r[belong[x]];++i)
	  h[i]+=k;
	for(int i=l[belong[y]];i<=y;++i)
	  h[i]+=k;
	px(belong[x]),px(belong[y]);
	for(int i=belong[x]+1;i<belong[y];++i)
	  sig[i]+=k;
}

int sum(int x,int y,int k){
	int ret=0;
	if(belong[x]==belong[y]){
		for(int i=x;i<=y;++i)
		  if(h[i]+sig[belong[x]]>=k)
		    ret++;
		return ret;
	}
	for(int i=x;i<=r[belong[x]];++i)
	  if(h[i]+sig[belong[x]]>=k)
	    ret++;
	for(int i=l[belong[y]];i<=y;++i)
	  if(h[i]+sig[belong[y]]>=k)
	    ret++;
	for(int i=belong[x]+1;i<belong[y];++i)
	  ret+=calc(i,k-sig[i]);
	return ret;
}

int main(){
	n=Read(),q=Read();
	for(int i=1;i<=n;++i)
	  h[i]=Read();
	fk();
	while(q--){
		char cz[5];
		scanf("%s",cz);
		int l=Read(),r=Read(),k=Read();
		if(cz[0]=='M')
		  add(l,r,k);
		else
		  cout<<sum(l,r,k)<<'\n';
	}
	return 0;
}

 

posted @ 2019-01-19 09:45  Ishtar~  阅读(80)  评论(0编辑  收藏