zoukankan      html  css  js  c++  java
  • [LOJ] 分块九题 4

    https://loj.ac/problem/6280

    区间修改,区间求和。

    本来线段树的活。

    //Stay foolish,stay hungry,stay young,stay simple
    #include<iostream>
    #include<cstdio>
    #include<cctype>
    #include<cmath>
    
    using namespace std;
    
    typedef long long ll;
    
    const int MAXN=500005;
    
    ll sum[MAXN],r[MAXN],l[MAXN],inc[MAXN];
    ll a[MAXN],bl[MAXN],block;
    ll n,m,num;
    
    inline ll read_d(){
        ll ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c)) f=c=='-'?-1:1;
        while(isdigit(c)){
            ret*=10;ret+=c-'0';c=getchar();
        }
        return ret*f;
    }
    
    inline void write(ll x)
    {
        if(x<0) x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    
    inline void build(){
        block=sqrt(n);
        num=n/block;
        if(n%block) num++;
        for(int i=1;i<=num;i++){
            l[i]=(i-1)*block+1;
            r[i]=i*block;
        }
        for(int i=1;i<=n;i++)
            bl[i]=(i-1)/block+1;
        r[num]=n;
        for(int i=1;i<=num;i++)
            for(int j=l[i];j<=r[i];j++)
                sum[i]+=a[j];
    }
    
    
    inline void updata(ll x,ll y,ll w){
        if(bl[x]==bl[y]){
            for(int i=x;i<=y;i++) a[i]+=w;
            sum[bl[x]]+=w*(y-x+1);
            return ;
        }
        for(int i=x;i<=r[bl[x]];i++)
            a[i]+=w,sum[bl[i]]+=w;
        for(int i=bl[x]+1;i<=bl[y]-1;i++)
            inc[i]+=w;
        for(int i=l[bl[y]];i<=y;i++)
            a[i]+=w,sum[bl[i]]+=w;
    }
    
    inline ll query(int x,int y){
        ll ret=0;
        if(bl[x]==bl[y]){
            for(int i=x;i<=y;i++) ret+=a[i]+inc[bl[i]];
            return ret;
        }
        for(int i=x;i<=r[bl[x]];i++) ret+=a[i]+inc[bl[i]];
        for(int i=bl[x]+1;i<=bl[y]-1;i++)
            ret+=sum[i]+inc[i]*(r[i]-l[i]+1);
        for(int i=l[bl[y]];i<=y;i++) ret+=a[i]+inc[bl[i]];
        return ret;
    }
    
    int main(){
        n=read_d();
        m=n;
        for(int i=1;i<=n;i++)
            a[i]=read_d(); 
        build();
        for(int i=1;i<=m;i++){
            ll q,x,y,z;
            q=read_d();
            x=read_d();
            y=read_d();
            z=read_d(); 
            if(q==0) updata(x,y,z);
            else write(query(x,y)%(z+1)),putchar('
    ');//讲道理是得query里每步模的
        }
        return 0;
    }
    

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247437.html

  • 相关阅读:
    后台java,前台extjs文件下载
    gridPanel可拖拽排序
    Extjs 获取输入框焦点,并选中值
    java poi对Excel文件加密
    java poi 读取有密码加密的Excel文件
    SSL 与 数字证书 的基本概念和工作原理
    splay树
    树剖版lca
    树链剖分
    kruskal重构树
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247437.html
Copyright © 2011-2022 走看看