zoukankan      html  css  js  c++  java
  • 成都磨子桥技工学校 / 数据结构 Challenge 4

    描述

    给一个长为N的数列,有M次操作,每次操作时以下三种之一:

    (1)修改数列中的一个数

    (2)求数列中某连续一段所有数的两两乘积的和 mod 1000000007

    (3)求数列中某连续一段所有相邻两数乘积的和 mod 1000000007

    1<=N<=10^5,1<=M<=10^5,输入保证合法,且所有整数可用带符号32位整型存储。

    题解

    比较简单,主要是维护第二个信息觉得有点意思,现在已经知道两个小区间内每个元素乘积和,那么合并之后增加的就是来自两个区间的元素的乘积,很容易想到乘法分配律,只要维护区间和即可。还有就是取模恶心到我了,模了之后在外面玩随便查错才发现查询有个小地方写错了(哭了)。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn=100005;
    const int mod=1000000007;
    int n,m,cnt,root;
    ll a[maxn];
    struct tree{
      int ls,rs;
      ll sum,mul1,mul2;//mul1:区间相邻的数的乘积和 mul2:两两乘积和
      ll lnum,rnum;
    }tr[maxn<<1];
    
    template<class T>inline void read(T &x){
      x=0;int f=0;char ch=getchar();
      while(!isdigit(ch)) {f|=(ch=='-');ch=getchar();}
      while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
      x= f ? -x : x ;
    }
    
    void update(tree &ret,tree lx,tree ry){
      ret.lnum=lx.lnum;
      ret.rnum=ry.rnum;
      ret.sum=(lx.sum+ry.sum)%mod;
      ret.mul1=((lx.mul1+ry.mul1)%mod+lx.rnum*ry.lnum%mod)%mod;
      ret.mul2=((lx.mul2+ry.mul2)%mod+lx.sum*ry.sum%mod)%mod;
    }
    
    void update(int rt){
      update(tr[rt],tr[tr[rt].ls],tr[tr[rt].rs]);
    }
    
    void build(int &rt,int l,int r){
      rt=++cnt;
      if(l==r){
        ll val=(a[l]%mod+mod)%mod;
        tr[rt]=(tree){0,0,val,0,0,val,val};
        return ;
      }
      int mid=(l+r)>>1;
      build(tr[rt].ls,l,mid);
      build(tr[rt].rs,mid+1,r);
      update(rt);
    }
    
    void modify(int rt,int l,int r,int pos,ll val){
      if(l==r){
        tr[rt]=(tree){0,0,val,0,0,val,val};
        return ;
      }
      int mid=(l+r)>>1;
      if(pos<=mid) modify(tr[rt].ls,l,mid,pos,val);
      else modify(tr[rt].rs,mid+1,r,pos,val);
      update(rt);
    }
    
    tree query(int rt,int l,int r,int a_l,int a_r){
      if(a_l<=l&&r<=a_r) return tr[rt];
      int mid=(l+r)>>1;
      if(a_r<=mid) return query(tr[rt].ls,l,mid,a_l,a_r);
      if(mid<a_l) return query(tr[rt].rs,mid+1,r,a_l,a_r);
      tree ret,x,y;
      x=query(tr[rt].ls,l,mid,a_l,a_r);
      y=query(tr[rt].rs,mid+1,r,a_l,a_r);
      update(ret,x,y);
      return ret;
    }
    
    int main(){
      read(n);read(m);
      for(int i=1;i<=n;i++) read(a[i]);
      build(root,1,n);
      for(int i=1;i<=m;i++){
        char op[2];
        scanf("%s",op);
        if(op[0]=='M'){
          int pos;
          ll val;
          read(pos);read(val);
          val=(val%mod+mod)%mod;
          modify(1,1,n,pos,val);
        }
        else if(op[0]=='Q'){
          int l,r;
          read(l);read(r);
          printf("%lld
    ",query(1,1,n,l,r).mul2);
        }
        else {
          int l,r;
          read(l);read(r);
          printf("%lld
    ",query(1,1,n,l,r).mul1);
        }
      }
    }
    View Code
  • 相关阅读:
    419. Battleships in a Board
    150. Evaluate Reverse Polish Notation
    153. Find Minimum in Rotated Sorted Array
    319. Bulb Switcher
    223. Rectangle Area
    iOS 常用到的宏#define
    VRAR 使用 SceneKit
    VR、AR、MR定义区别
    Swift 开源项目练习应用
    Swift3.0 UITextField
  • 原文地址:https://www.cnblogs.com/sto324/p/11379898.html
Copyright © 2011-2022 走看看