• 分块模板


    区间修改,区间求值

     1 const int N=100010;
     2 ll a[N],sum[N],add[N];
     3 int L[N],R[N],pos[N];
     4 int n,m,ds;
     5 
     6 void modify(int l,int r,ll k)
     7 {
     8     int p=pos[l],q=pos[r];
     9     if(p==q)
    10     {
    11         FOR(i,l,r) a[i]+=k;
    12         sum[p]+=(r-l+1)*k;
    13         return;
    14     }
    15     FOR(i,p+1,q-1) add[i]+=k;
    16     FOR(i,l,R[p]) a[i]+=k;
    17     sum[p]+=(R[p]-l+1)*k;
    18     FOR(i,L[q],r) a[i]+=k;
    19     sum[q]+=(r-L[q]+1)*k;
    20 }
    21 
    22 ll query(int l,int r)
    23 {
    24     int p=pos[l],q=pos[r];
    25     ll ans=0;
    26     if(p==q)
    27     {
    28         FOR(i,l,r) ans+=a[i];
    29         ans+=add[p]*(r-l+1);
    30         return ans;
    31     }
    32     FOR(i,p+1,q-1)
    33         ans+=sum[i]+add[i]*(R[i]-L[i]+1);
    34     FOR(i,l,R[p]) ans+=a[i];
    35     ans+=(R[p]-l+1)*add[p];
    36     FOR(i,L[q],r) ans+=a[i];
    37     ans+=(r-L[q]+1)*add[q];
    38     return ans;
    39 }
    40 
    41 int main()
    42 {
    43     scanf("%d%d",&n,&m);
    44     FOR(i,1,n) scanf("%lld",&a[i]);
    45     ds=sqrt(n);
    46     FOR(i,1,ds)
    47         L[i]=(i-1)*ds+1,
    48         R[i]=i*ds;
    49     if(R[ds]<n) ++ds,L[ds]=R[ds-1]+1,R[ds]=n;
    50     FOR(i,1,ds) FOR(j,L[i],R[i]) pos[j]=i,sum[i]+=a[j];
    51     int opt,l,r;ll k;
    52     while(m--)
    53     {
    54         scanf("%d%d%d",&opt,&l,&r);
    55         if(opt==1)
    56         {
    57             scanf("%lld",&k);
    58             modify(l,r,k);
    59         }
    60         else printf("%lld
    ",query(l,r));
    61     }
    62     return 0;
    63 }
  • 相关阅读:
    实验一框架选择及其分析
    站立会议(一)
    关于有多少个1的计算
    寻找水王问题
    如何买到更便宜的书
    NABCD
    二维数组首尾相连求最大子矩阵
    环数组求最大子数组的和
    二维数组求最大矩阵
    关于铁道大学基础教学楼电梯调查
  • 原文地址:https://www.cnblogs.com/universeplayer/p/10544424.html
Copyright © 2020-2023  润新知