POJ 3468 A Simple Problem with Integers (分块)

xiaoxiao2021-02-28  95

题意:

        N个数,M次操作。每次操作 Q  X  Y 代表查询 X 到 Y 的区间和, C  X  Y  Z 代表将区间 X 到 Y 中的所有数加 Z

思路:

        分块区间修改,查询。

另:线段树解法

代码:

#include <cstdio> #include <iostream> #include <cmath> using namespace std; const int MAXN=1e5+7; int a[MAXN],n,m; int num,l[MAXN],r[MAXN],belong[MAXN],blen; long long sum[MAXN],lazy[MAXN]; void build(){ blen=sqrt((double)n); num=n/blen;if(n%blen) num++; for(int i=1;i<=num;i++) l[i]=(i-1)*blen+1,r[i]=i*blen;r[num]=n; for(int i=1;i<=num;i++){ sum[i]=0; lazy[i]=0; for(int j=l[i];j<=r[i];j++){ belong[j]=i; sum[i]+=a[j]; } } } long long query(int st,int en){ long long ans=0; if(belong[st]==belong[en]){ for(int i=st;i<=en;i++) ans+=a[i]+lazy[belong[st]]; }else{ for(int i=st;i<=r[belong[st]];i++) ans+=a[i]+lazy[belong[st]]; for(int i=belong[st]+1;i<=belong[en]-1;i++) ans+=sum[i]+lazy[i]*(r[i]-l[i]+1); for(int i=l[belong[en]];i<=en;i++) ans+=a[i]+lazy[belong[en]]; } return ans; } void update(int st,int en,long long v){ if(belong[st]==belong[en]){ for(int i=st;i<=en;i++) a[i]+=v,sum[belong[st]]+=v; }else{ for(int i=st;i<=r[belong[st]];i++) a[i]+=v,sum[belong[st]]+=v; for(int i=belong[st]+1;i<=belong[en]-1;i++) lazy[i]+=v; for(int i=l[belong[en]];i<=en;i++) a[i]+=v,sum[belong[en]]+=v; } } int main() { char op; int l,r; long long x; while(scanf("%d%d",&n,&m)!=-1){ for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(); for(int i=1;i<=m;i++){ getchar(); scanf("%c %d %d",&op,&l,&r); if(op=='Q'){ printf("%lld\n",query(l,r)); }else{ scanf("%lld",&x); update(l,r,x); } } } }

转载请注明原文地址: https://www.6miu.com/read-84446.html

最新回复(0)