求助一道站外分块题
  • 板块学术版
  • 楼主Engulf
  • 当前回复4
  • 已保存回复4
  • 发布时间2022/2/21 18:56
  • 上次更新2023/10/28 07:59:37
查看原帖
求助一道站外分块题
482728
Engulf楼主2022/2/21 18:56

原题链接

LOJ 那边根本没人/kk 只能来洛谷求助了。

分块模板都能 TLE,只有 30pts。

#include <bits/stdc++.h>
using namespace std;

inline int read(){
	int x=0,f=0;char ch=getchar();
	while(!isdigit(ch))f^=!(ch^45),ch=getchar();
	while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}
inline void write(int x){
	if(x<0)x=-x,putchar('-');
	if(x>=10)write(x/10);
	putchar(x%10+'0');
}
inline void writeln(int x){write(x);puts("");}

int n;
int a[50005];

int block,num;
int L[50005],R[50005];
int pos[50005];
int sum[50005],add[50005];

void build(){
	block=sqrt(n);
	num=n/block;
	if(n%block)num++;
	for(int i=1;i<=num;i++){
		L[i]=(i-i)*block+1;
		R[i]=i*block;
	}
	R[num]=n;
	for(int i=1;i<=num;i++){
		for(int j=L[i];j<=R[i];j++){
			pos[j]=i;
			sum[i]+=a[j];
		}
	}
}

void update(int l,int r,int k){
	int x=pos[l],y=pos[r];
	if(x==y){
		for(int i=l;i<=r;i++){
			a[i]+=k;
			sum[x]+=k;
		}
	}else{
		for(int i=x+1;i<=y-1;i--){
			add[i]+=k;
		}
		for(int i=l;i<=R[x];i++){
			a[i]+=k;
			sum[x]+=k;
		}
		for(int i=L[y];i<=r;i++){
			a[i]+=k;
			sum[y]+=k;
		}
	}
}

int query(int l,int r){
	int x=pos[l],y=pos[r];
	int ans=0;
	if(x==y){
		for(int i=l;i<=r;i++)ans+=a[i];
		ans+=add[x]*(r-l+1);
	}
	else{
		for(int i=x+1;i<=y-1;i++){
			ans+=sum[i]+add[i]*(R[i]-L[i]+1);
		}
		for(int i=l;i<=R[x];i++){
			ans+=a[i];
		}
		ans+=add[x]*(R[x]-l+1);
		for(int i=L[y];i<=r;i++){
			ans+=a[i];
		}
		ans+=add[y]*(r-L[y]+1);
	}
	return ans;
}

int query(int p){
	int ans=a[p];
	ans+=add[pos[p]];
	return ans;
}

int main(){
	n=read();
	for(int i=1;i<=n;i++)a[i]=read();	
	build();
	while(n--){
		int op=read(),l=read(),r=read(),c=read();
		if(op==0)update(l,r,c);
		else writeln(query(r));
	}
	#ifndef ONLINE_JUDGE
	system("pause");
	#endif
	return 0;
}
2022/2/21 18:56
加载中...