分块最后一个点 TLE 求调
  • 板块P2357 守墓人
  • 楼主Lofty
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/11/16 22:30
  • 上次更新2023/11/17 07:30:25
查看原帖
分块最后一个点 TLE 求调
591863
Lofty楼主2023/11/16 22:30
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define TP template<typename T>
#define TP_ template<typename T,typename ... T_>
namespace IO
{
	TP void read(T &x)
	{
		x=0;int f=0;char ch=getchar();
		for(;ch<'0'||ch>'9';ch=getchar())ch=='-'&&(f=1);
		for(;ch>='0'&&ch<='9';ch=getchar())x=(x*10)+(ch^48);
		f&&(x=-x);
	}
	TP_ void read(T &x,T_&...y){read(x);read(y...);}
	TP void write(T x){x<0&&(putchar('-'),x=-x);static int sta[35];int top=0;do{sta[++top]=x%10,x/=10;}while(x);while(top)putchar(sta[top--]^48);}
	TP void writeln(const T x){write(x);puts("");}
	TP void writesp(const T x){write(x);putchar(' ');}
	TP_ void writeln(const T x,T_ ...y){writesp(x);writeln(y...);}
	TP void debugsp(const T x){fprintf(stderr,"%d ",x);}
	TP void debug(const T x){fprintf(stderr,"%d\n",x);}
	TP_ void debug(const T x,const T_...y){debugsp(x);debug(y...);}
	TP inline T max(const T &a,const T &b){return a>b?a:b;}
	TP inline T min(const T &a,const T &b){return a<b?a:b;}
	TP inline void swap(T &a,T &b){static T t;t=a;a=b;b=t;}
	TP inline T abs(const T &a){return a>0?a:-a;}
}
using namespace IO;
using LL=long long;
constexpr int N=2e5+5;
constexpr int M=5e2+5;
int L[N],R[N],pos[N];
LL sum[M],a[N],lazy[M];
int block;
int n,m;
inline void modify(int l,int r,LL c)
{
	int x=pos[l],y=pos[r];
	if(y-x<2)
	{
		for(int i=l;i<=r;i++)
			a[i]+=c;
		return ;
	}
	for(int i=l;i<=R[x];i++)
		a[i]+=c,sum[pos[i]]+=c;
	for(int i=L[y];i<=r;i++)
		a[i]+=c,sum[pos[i]]+=c;
	for(int i=x+1;i<=y-1;i++)
		lazy[i]+=c,sum[i]+=c*(R[i]-L[i]+1);
}
inline LL query(int l,int r)
{
	int x=pos[l],y=pos[r];
	LL ans=0;
	if(y-x<2)
	{
		for(int i=l;i<=r;i++)
			ans+=a[i]+lazy[pos[i]];
		return ans;
	}
	for(int i=l;i<=R[x];i++)
		ans+=a[i]+lazy[pos[i]];
	for(int i=L[y];i<=r;i++)
		ans+=a[i]+lazy[pos[i]];
	for(int i=x+1;i<=y-1;i++)
		ans+=sum[i];
	return ans;
}
int main()
{
	read(n,m);
	block=n/sqrt(n);
	for(int i=1;i<=n;i++)
		read(a[i]);
	for(int i=1;i<=block;i++)
	{
		L[i]=R[i]+1;
		R[i]=L[i]+block-1;
	}
	if(R[block]<n)
	{
		block++;
		L[block]=L[block-1]+1;
		R[block]=n;
	}
	for(int i=1;i<=block;i++)
		for(int j=L[i];j<=R[i];j++)
			pos[j]=i,sum[i]+=a[j];
	while(m--)
	{
		int op;read(op);
		if(op==1)
		{
			int l,r;
			LL c;
			read(l,r,c);
			modify(l,r,c);
		}
		else if(op==2)
		{
			LL c;read(c);
			a[1]+=c;
		}
		else if(op==3)
		{
			LL c;read(c);
			a[1]-=c;
		}
		else if(op==4)
		{
			int l,r;read(l,r);
			writeln(query(l,r));
		}
		else
		{
			writeln(a[1]+lazy[pos[1]]);
		}
	}
	return 0;
}
2023/11/16 22:30
加载中...