zoukankan      html  css  js  c++  java
  • cogs 2632. [HZOI 2016] 数列操作d

    2632. [HZOI 2016] 数列操作d

    ★★★   输入文件:segment.in   输出文件:segment.out   简单对比
    时间限制:3 s   内存限制:512 MB

    【题目描述】

    一个长度为n的序列,一开始序列数的权值都是0,有m次操作

    支持两种操作:

    1 L R x,给区间[L,R]内位置为pos的数加上(pos-L)*x

    0 L R,查询区间[L,R]内的权值和

    最终答案对109+7取模。

    【输入格式】

    第一行两个数n,m,表示序列长度和操作次数

    接下来m行,每行描述一个操作,有如下两种情况:

    1 L R x,给区间[L,R]内位置为pos的数加上(posL)×x

    0 L R,查询区间[L,R]内的权值和

    【输出格式】

    每一个0操作输出一个整数模109+7

    【样例输入】

    5 5
    0 2 3
    1 4 5 1
    1 1 5 5
    0 1 4
    0 2 3
    

    【样例输出】

    0
    30
    15 

    【提示】

    对于30%的数据 n,m<=2000

    对于100%的数据,n,m<=300000

    保证读入的都是非负整数,所有的x<=10000

    【来源】

    感谢神犇
    非常感谢神犇

    非常非常感谢神犇

     

     
       

    #include<bits/stdc++.h>
    #define ll long long
    #define INF 1000000007
    #define maxn 300005
    using namespace std;
    ll S[maxn];
    ll lz1[maxn<<2],lz2[maxn<<2];//lz1 就是记录那个-L *x的  lz2就是记录 pos*x的  
    ll dat[maxn<<2];
    void Add(int rt,int l,int r,int ss,int tt,ll qx,ll posx){ 
        if(ss>r||tt<l) return;//判断是否越界 
        if(ss<=l&&r<=tt){//全部包含 
            lz1[rt]=(lz1[rt]+qx)%INF;//永久化标记 
            lz2[rt]=(lz2[rt]+posx)%INF;
            dat[rt]=(dat[rt]+qx*(r-l+1)%INF+posx*((S[r]-S[l-1])%INF)%INF)%INF;// (S[r]-S[l-1])就是那一段等差数列的和 预处理出来了直接作一个差就行了  
            return;
        }
        int mid=(l+r)>>1;
        Add(rt*2,l,mid,ss,tt,qx,posx);Add(rt*2+1,mid+1,r,ss,tt,qx,posx);
        dat[rt]=(dat[rt*2]+dat[rt*2+1]+lz1[rt]*(r-l+1)%INF+lz2[rt]*((S[r]-S[l-1])%INF)%INF)%INF;
    }
    ll Get(int rt,int l,int r,int ss,int tt){
        if(ss>r||tt<l) return 0;
        if(ss<=l&&r<=tt) return dat[rt];
          int lll=max(l,ss);
        int rr=min(r,tt);
        int mid=(l+r)>>1;
        return (lz1[rt]*(rr-lll+1)%INF+lz2[rt]*((S[rr]-S[lll-1])%INF)%INF+Get(rt*2,l,mid,ss,tt)+Get(rt*2+1,mid+1,r,ss,tt))%INF;
    }
    int main(){
        freopen("segment.in","r",stdin);freopen("segment.out","w",stdout);
        int n,m;scanf("%d%d",&n,&m);//输入 不说了 哈哈 
        for(int i=1;i<=n;i++) S[i]=S[i-1]+i;//这里就是预处理一个前缀和 
        for(int i=1;i<=m;i++){
            int Type;scanf("%d",&Type);
            if(Type){
                int l,r;ll x,posx;scanf("%d%d%lld",&l,&r,&x);
                posx=(INF-l)*x%INF;//posx 就是那个-L  这里加上一个INF 是因为——L是负数  会炸的!! 
                Add(1,1,n,l,r,posx,x);
            }
            else{
                int l,r;scanf("%d%d",&l,&r);
                printf("%lld
    ",Get(1,1,n,l,r)%INF);
            }
        }
        return 0;
    }
  • 相关阅读:
    Webpack配置
    闭包函数
    Vue2.0(一) 新手搭建环境
    用python编写一个合格的ftp程序,思路是怎样的?
    项目流程规范
    python: 基本数据类型 与 内置函数 知识整理
    前端知识 备忘录
    架构的演化路线
    深入理解并使用python的模块与包
    jquery 知识整理
  • 原文地址:https://www.cnblogs.com/Tidoblogs/p/11308218.html
Copyright © 2011-2022 走看看