洛谷 P2801 教主的魔法 题解

本小妞迷上赌 提交于 2019-11-30 15:05:14

题面

刚看到这道题的时候用了个树状数组优化前缀和差分的常数优化竟然AC了?(这数据也太水了吧~)

本人做的第一道分块题,调试了好久好久,最后竟然没想到二分上还会出错!(一定要注意)仅此纪念;

#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
int a[1000010],b[1000010],belong[1000010]; //原来的 
int lazy[1000010],l[1000010],r[1000010]; //块上的 
int block,tot,n,m;
void build()
{
	block=sqrt(n);
	tot=n/block;
	if(n%block){
		++tot;
	}
	for(register int i=1;i<=n;i++){
		b[i]=a[i];
		belong[i]=(i-1)/block+1;
	}
	for(register int i=1;i<=tot;i++){
		l[i]=(i-1)*block+1;
		r[i]=i*block;
	}
	r[tot]=n;
	for(register int i=1;i<=tot;i++){
		sort(b+l[i],b+r[i]+1);
	}
	return;
}
void change(int x,int y,int k)
{
	if(belong[x]==belong[y]){
		for(register int i=x;i<=y;i++){
			a[i]+=k;
		}
		for(register int i=l[belong[x]];i<=r[belong[x]];i++){
			b[i]=a[i];
		}
		sort(b+l[belong[x]],b+r[belong[x]]+1);
		return ;
	}
	for(register int i=x;i<=r[belong[x]];i++){
		a[i]+=k;
	}
	for(register int i=l[belong[x]];i<=r[belong[x]];i++){
		b[i]=a[i];
	}
	sort(b+l[belong[x]],b+r[belong[x]]+1);
	for(register int i=l[belong[y]];i<=y;i++){
		a[i]+=k;
	}
	for(register int i=l[belong[y]];i<=r[belong[y]];i++){
		b[i]=a[i];
	}
	sort(b+l[belong[y]],b+r[belong[y]]+1);
	for(register int i=belong[x]+1;i<=belong[y]-1;i++){
		lazy[i]+=k;
	}
}
int query(int x,int y,int goal)
{
	int ans=0;
	if(belong[x]==belong[y]){
		for(register int i=x;i<=y;i++){
			if(a[i]+lazy[belong[x]]>=goal) ++ans;
		}
		return ans;
	}
	for(register int i=x;i<=r[belong[x]];i++){
		if(a[i]+lazy[belong[x]]>=goal) ++ans;
	}
	for(register int i=l[belong[y]];i<=y;i++){
		if(a[i]+lazy[belong[y]]>=goal) ++ans;
	}
	for(register int i=belong[x]+1;i<=belong[y]-1;i++){
		int L=l[i],R=r[i],mid;
		while(L<R){
			int mid=(L+R)/2;
			if(b[mid]+lazy[i]>=goal){
				R=mid;
			}
			else{
				L=mid+1;
			}
		}
		if(L==r[i]){
			ans+=((b[L]+lazy[i])>=goal);
			continue;
		}
		ans+=(r[i]-L+1);
	}
	return ans;
} 
int main()
{
	cin>>n>>m;
	for(register int i=1;i<=n;i++) scanf("%d",&a[i]);
	build();
	for(register int i=1;i<=m;i++){
		char type;
		int x,y,k;
		cin>>type>>x>>y>>k;
		if(type=='M'){
			change(x,y,k);
		}
		else{
			cout<<query(x,y,k)<<endl;
		}
	}
} 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!