zoukankan      html  css  js  c++  java
  • 分块动态求和

    不会的同学可以先参考这个博客

    https://blog.csdn.net/weixin_43914593/article/details/108474903

    题目;loj6280

    题目描述

    给出一个长为  的数列,以及  个操作,操作涉及区间加法,区间求和。

    输入格式

    第一行输入一个数字 

    第二行输入  个数字,第  个数字为 ,以空格隔开。

    接下来输入  行询问,每行输入四个数字 ,以空格隔开。

    若 ,表示将位于  的之间的数字都加 

    若 ,表示询问位于  的所有数字的和 

    #pragma GCC optimize(1)
    #pragma GCC optimize(2)
    #pragma GCC optimize(3,"Ofast","inline")
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    template <typename Tp>
    void read(Tp &x){
        x=0;char ch=1;int fh;
        while(ch!='-'&&(ch>'9'||ch<'0')){
            ch=getchar();
        }
        if(ch=='-'){
            fh=-1;ch=getchar();
        }else fh=1;
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
        }
        x*=fh;
    }
    inline char read1()
    {
        register char ch=getchar();
        while(ch<'A'||ch>'M')ch=getchar();
        return ch;
    }
    const int maxn=1e6+100;
    ll a[maxn],l[maxn],r[maxn],belong[maxn],lazy[maxn],ans;
    ll sum[maxn];
    ll n,op,x,y,k,block,tot;
    void build(){
        block=sqrt(n);
        tot=n/block;
        if(n%block){
            tot++;
        }
        for(register int i=1;i<=n;i++){
            belong[i]=(i-1)/block+1;
        }
        for(register int i=1;i<=tot;i++){
            l[i]=(i-1)*block+1;
            r[i]=i*block;
        }
        r[tot]=n;
        for(int i=1; i<=tot; i++){                 //遍历所有的块
            for(int j=l[i]; j<=r[i];j++)      //遍历块i内的所有元素
                sum[i] += a[j];//一个块中的和 
        } 
    }
    void change(){
        if(belong[x]==belong[y]){
            for(register int i=x;i<=y;i++){
                a[i]+=k;
                sum[belong[x]]+=k;
            }
        }
        else{
            for(register int i=x;i<=r[belong[x]];i++){
                a[i]+=k;
                sum[belong[x]]+=k;
            }
            for(register int i=l[belong[y]];i<=y;i++){
                a[i]+=k;
                sum[belong[y]]+=k;
            }
            for(register int i=belong[x]+1;i<belong[y];i++){
                lazy[i]+=k;//懒惰标记 
            }
        } 
    }
    void ask(){
        ans=0;
        if(belong[x]==belong[y]){
            for(register int i=x;i<=y;i++){
                ans=(ans+lazy[belong[x]]+a[i])%(k+1);//不要忘记懒惰标记 
            }
            printf("%lld
    ",ans%(k+1));
        }
        else{
            for(register int i=x;i<=r[belong[x]];i++){
                ans=(ans+lazy[belong[x]]+a[i])%(k+1); 
            }
            for(register int i=l[belong[y]];i<=y;i++){
                ans=(ans+lazy[belong[y]]+a[i])%(k+1);
            }
            for(int i=belong[x]+1;i<belong[y];i++){
                ans=(ans+1ll*sum[i]+(r[i]-l[i]+1)*lazy[i])%(k+1);//不要忘记懒惰标记,和sum[i] 
            } 
            printf("%lld
    ",ans%(k+1));
        }
        
    } 
    int main(){
        read(n);
        for(int i=1;i<=n;i++){
            read(a[i]);
        }
        build();
        for(int i=1;i<=n;i++){
            read(op),read(x),read(y),read(k);
            if(op==0){
                change();
            }
            else{
                ask();
            }
        } 
    }
  • 相关阅读:
    [转贴]分贝是个什么东西?(好东东)
    [VDSP中的Warning]function declared implicitly
    [VDSP中的Warning]explicit type is missing
    [VDSP中的Warning]integer conversion resulted in a change of sign
    Java 一键多列的map
    springboot 使用邮件服务发送验证码 以及在阿里云服务器的配置
    图像处理之入门篇
    javascript怎么可以判断单选复选按钮是否选中,且传值
    QQ,MSN,SKYPE等在线状态代码 (转)
    在Access中SQL的调试
  • 原文地址:https://www.cnblogs.com/lipu123/p/13672961.html
Copyright © 2011-2022 走看看