蒟蒻求助:我试图使用分块,却……30pts
查看原帖
蒟蒻求助:我试图使用分块,却……30pts
497333
I_Flipped楼主2021/10/29 21:06

蒟蒻求助

分块思想做线段树(我是伞兵

但我还是想知道错在哪里

蟹蟹了!

#include<algorithm>
#include<iostream>
#include<string>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+5;

inline int read(){
    char c=getchar();int f=1,x=0;
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-48;c=getchar();}
    return x*f;
}

ll n,m,sq,pd,x,y,k;
ll a[N],st[N],ed[N],bel[N],siz[N],sum[N],mark[N];

void init(int n){
	sq=sqrt(n);
	for(int i=1;i<=sq;++i){
		st[i]=sq*(i-1)+1;
		ed[i]=sq*i;
	}
	ed[sq]=n;
	
	for(int i=1;i<=sq;++i)
		for(int j=st[i];j<=ed[i];++j)
			bel[j]=i;//判断从属关系 
	
	for(int i=1;i<=sq;++i)
		siz[i]=ed[i]-st[i]+1;
}

void change(int x,int y,int k){
	if(bel[x]==bel[y]){
		for(int i=x;i<=y;++i){
			a[i]+=k;
			sum[bel[i]]+=k;
		}
	}
	else{
		for(int i=x;i<=ed[bel[x]];++i){
			a[i]+=k;
			sum[bel[x]]+=k;
		}
		for(int i=st[bel[y]];i<=y;++i){
			a[i]+=k;
			sum[bel[x]]+=k;
		}
		for(int i=bel[x]+1;i<bel[y];++i)mark[i]+=k;
	}
}

ll query(int x,int y){
	ll ans=0;
	if(bel[x]==bel[y]){
		for(int i=x;i<=y;++i){
			ans+=a[i]+mark[bel[i]];
		}
	}
	else{
		for(int i=x;i<=ed[bel[x]];++i)
			ans+=a[i]+mark[bel[i]];
		for(int i=st[bel[y]];i<=y;++i)
			ans+=a[i]+mark[bel[i]];
		for(int i=bel[x]+1;i<bel[y];++i)
			ans+=sum[i]+mark[i]*siz[i];
	}
	return ans;
}

int main(){
//	freopen("ans.out","w",stdout);
	
	n=read(),m=read();
	init(n);
	for(int i=1;i<=n;++i)a[i]=read();
	for(int i=1;i<=sq;++i)
		for(int j=st[i];j<=ed[i];++j)
			sum[i]+=a[j];
	while(m--){
		pd=read(),x=read(),y=read();
		if(pd==1){
			k=read();
			change(x,y,k);
		}
		else printf("%lld\n",query(x,y));
	}
	return 0;
}
2021/10/29 21:06
加载中...