站外分块入门题求调(loj6278)
  • 板块学术版
  • 楼主Tangent233
  • 当前回复10
  • 已保存回复10
  • 发布时间2022/5/1 20:26
  • 上次更新2023/10/28 02:27:48
查看原帖
站外分块入门题求调(loj6278)
264548
Tangent233楼主2022/5/1 20:26
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+10,blen=sqrt(maxn)+10;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
long long n,num[maxn]/*,upd[blen]*/,plu[blen],use[blen];
int getb(int x)
{
	return (x-1)/blen+1;
}
void updata(int blc)
{
	int lp=(blc-1)*blen+1,rp=blc*blen;
	for(int i=lp;i<=min(rp,(int)n);i++)
		use[i]=num[i];
	sort(use+lp,use+rp+1);
}
void init()
{
	for(int i=1;i<=getb(n);i++) updata(i);
}
void add(int l,int r,int c)
{
	int bl=getb(l),br=getb(r);
	for(int i=l;i<=min(r,bl*blen);i++)
		num[i]+=c;
	updata(bl);
	if(bl!=br)
	{	
		for(int i=(br-1)*blen+1;i<=r;i++)
			num[i]+=c;
		updata(br);
	}
	for(int i=bl+1;i<=br-1;i++)
		plu[i]+=c;
}
int fnd(int ul,int ur,long long val)
{
	int l=ul,r=ur;
	int ans=l;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(use[mid]<val)
		{
			ans=mid;
			l=mid+1;
		}
		else r=mid-1;
	}
	return ans-ul+1;
}
int ask(int l,int r,long long c)
{
	int ans=0;
	int bl=getb(l),br=getb(r);
	for(int i=l;i<=min(r,bl*blen);i++)
		if(c>num[i]+plu[bl]) ans++;
	if(bl!=br)
		for(int i=(br-1)*blen+1;i<=r;i++)
			if(c>num[i]+plu[br]) ans++;
	for(int i=bl+1;i<=br-1;i++)
		ans+=fnd((i-1)*blen+1,i*blen,c-plu[i]);
	return ans;
}
int main()
{
	n=read();
	for(int i=1;i<=n;i++) num[i]=read();
	init();
	for(int i=1;i<=n;i++)
	{
		long long opt=read(),l=read(),r=read(),c=read();
		if(opt==0) add(l,r,c);
		if(opt==1) cout<<ask(l,r,c*c)<<endl;
	}
	return 0;
}

我是不是不应该手搓已有的轮子(

2022/5/1 20:26
加载中...