分块30pts求条

P3372 【模板】线段树 1

yzc001 @ 2024-08-06 10:51:22

#include<bits/stdc++.h>
using namespace std;
long long a[100010],k[1010],g[1010],n,q,w,l,r,v,x;
int main(){
    scanf("%lld%lld",&n,&q);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    x=sqrt(n);
    for(int i=1;i<=x;i++)for(int j=1;j<=x;j++)k[i]+=a[(i-1)*x+j];//加和 
    while(q--){
        scanf("%lld",&w);
        if(w==1){
            scanf("%lld%lld%lld",&l,&r,&v);
            for(int i=l;i<=((l-1)/x+1)*x;i++)a[i]+=v;//暴力加 
            k[(l-1)/x+1]+=v*(((l-1)/x+1)*x-l+1);//加和 
            for(int i=(l-1)/x+2;i<(r-1)/x+1;i++)g[i]+=v;//整块修改
            //同上 
            for(int i=(r-1)/x*x+1;i<=r;i++)a[i]+=v; 
            k[(r-1)/x+1]+=v*(r-((r-1)/x*x+1)+1); 
        }else{
            v=0;
            scanf("%lld%lld",&l,&r);
            if((l-1)/x!=(r-1)/x) {
                for(int i=l;i<=((l-1)/x+1)*x;i++)v+=a[i];//暴力加 
                v+=g[(l-1)/x+1]*(((l-1)/x+1)*x-l+1);//加和 
                for(int i=(l-1)/x+2;i<(r-1)/x+1;i++)v+=k[i]+g[i]*x;//整块求和
                //同上
                for(int i=(r-1)/x*x+1;i<=r;i++)v+=a[i]; 
                v+=g[(r-1)/x+1]*(r-((r-1)/x*x+1)+1); 
            }else for(int i=l;i<=r;i++)v+=a[i];
            printf("%lld\n",v); 
        } 
        for(int i=1;i<=x;i++)printf("%lld %lld\n",k[i],g[i]);
        for(int i=1;i<=n;i++)printf("%lld\n",a[i]); 
    }
}

by five_rice_water @ 2024-08-06 11:03:14

线段树的模版 不然咱就写个线段树呢 也就几十行代码(实际是我不会分块)


by yzc001 @ 2024-08-06 11:22:52

(用线段树A了,但在练分块模板


|