• 洛谷P3373 【模板】线段树 2


    题目描述

    如题,已知一个数列,你需要进行下面三种操作:

    1.将某区间每一个数乘上x

    2.将某区间每一个数加上x

    3.求出某区间每一个数的和

    输入格式

    第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含3或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k

    操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k

    操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果

    输出格式

    输出包含若干行整数,即为所有操作3的结果。

    输入输出样例

    输入 #1
    5 5 38
    1 5 4 2 3
    2 1 4 1
    3 2 5
    1 2 4 2
    2 3 5 5
    3 1 4
    输出 #1
    17
    2

    说明/提示

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=1000,M<=10000

    对于100%的数据:N<=100000,M<=100000

    (数据已经过加强^_^)

           啊调这道水体调了一晚上果然我太弱了qaqq

          附上代码

          

      1 #include<bits/stdc++.h>
      2 #define re register int
      3 #define LL long long
      4 #define lson now<<1
      5 #define rson now<<1|1 
      6 #define maxn 1000000+5
      7 
      8 using namespace std;
      9 int n,m,mod,op,x,y,k;
     10 LL num[maxn];
     11 struct tree{
     12     LL sum,add,mul;
     13 }tr[maxn<<2];
     14 void build(int now,int l,int r)
     15 {
     16     tr[now].add=0;
     17     tr[now].mul=1;
     18     if(l==r)
     19     {
     20         tr[now].sum=num[l];
     21         return;
     22     }
     23     int mid=(l+r)>>1;
     24     build(lson,l,mid);
     25     build(rson,mid+1,r);
     26     tr[now].sum=(tr[lson].sum+tr[rson].sum)%mod;
     27     //显然不用加tr[now].sum 
     28 }
     29 void lazy(int now,int l,int r)
     30 {
     31     int mid=(l+r)>>1;
     32     tr[lson].sum=(tr[lson].sum*tr[now].mul%mod+tr[now].add*(mid-l+1)%mod)%mod;
     33     tr[rson].sum=(tr[rson].sum*tr[now].mul%mod+tr[now].add*(r-mid)%mod)%mod;
     34     tr[lson].mul=(tr[lson].mul*tr[now].mul)%mod;
     35     tr[rson].mul=(tr[rson].mul*tr[now].mul)%mod;
     36     tr[lson].add=(tr[lson].add*tr[now].mul%mod+tr[now].add)%mod;
     37     tr[rson].add=(tr[rson].add*tr[now].mul%mod+tr[now].add)%mod;
     38     //记得要乘tr[now].mul鸭 
     39     tr[now].add=0;
     40     tr[now].mul=1;
     41 }
     42 void refresh(int now,int L,int R,int l,int r,LL mu)
     43 {
     44    // if(l>R||r<L)
     45    // return;
     46     if(L<=l&&R>=r)
     47     {
     48         tr[now].sum=(tr[now].sum*mu)%mod;
     49         tr[now].add=(tr[now].add*mu)%mod;
     50         tr[now].mul=(tr[now].mul*mu)%mod;
     51         return;
     52     }
     53     lazy(now,l,r);
     54     int mid=(l+r)>>1;
     55     if(L<=mid) refresh(lson,L,R,l,mid,mu);
     56     if(R>mid)  refresh(rson,L,R,mid+1,r,mu);
     57     tr[now].sum=(tr[lson].sum+tr[rson].sum)%mod;
     58 }
     59 void refresh2(int now,int L,int R,int l,int r,int ad)
     60 {
     61 //    if(l>R||r<L)
     62 //    return;
     63    // cout<<l<<" "<<r<<" "<<tr[now].sum<<endl; 
     64     if(L<=l&&R>=r)
     65     {
     66 //        cout<<(r-l+1)<<endl;
     67 //        cout<<tr[now].sum<<endl;
     68 //        cout<<ad<<endl;
     69         tr[now].sum=(tr[now].sum+ad*(r-l+1)%mod)%mod;
     70         tr[now].add=(tr[now].add+ad)%mod;
     71 //        cout<<tr[now].sum<<" "<<tr[now].add<<endl;
     72         return;
     73     }
     74     lazy(now,l,r);
     75     int mid=(l+r)>>1;
     76 //    cout<<L<<" "<<R<<endl;
     77     if(L<=mid)  refresh2(lson,L,R,l,mid,ad);//不要再写错函数名了 
     78     if(R>mid)   refresh2(rson,L,R,mid+1,r,ad);
     79     tr[now].sum=(tr[lson].sum+tr[rson].sum)%mod;
     80 }
     81 LL query(int now,int l,int r,int L,int R)
     82 {
     83 //    if(L>r||R<l)
     84 //    return 0;
     85  //   cout<<l<<" "<<r<<" "<<tr[now].sum<<endl; 
     86     if(L<=l&&R>=r)
     87     return tr[now].sum%mod;
     88     lazy(now,l,r);
     89     int mid=(l+r)>>1;
     90     if(L>mid) return query(rson,mid+1,r,L,R)%mod;
     91     else if(R<=mid)
     92     return query(lson,l,mid,L,R)%mod;
     93     else return (query(lson,l,mid,L,R)+query(rson,mid+1,r,L,R))%mod;
     94  } 
     95 int main()
     96 {
     97     ios::sync_with_stdio(false);
     98     cin>>n>>m>>mod;
     99     for(re i=1;i<=n;i++)
    100     cin>>num[i],num[i]%=mod;
    101     build(1,1,n); 
    102     while(m--)
    103     {
    104         cin>>op;
    105         if(op==1)
    106         {
    107             cin>>x>>y>>k;
    108             refresh(1,x,y,1,n,k);
    109         }
    110         if(op==2)
    111         {
    112             cin>>x>>y>>k;
    113             refresh2(1,x,y,1,n,k); 
    114         }
    115         if(op==3)
    116         {
    117             cin>>x>>y;
    118             cout<<query(1,1,n,x,y)<<endl;
    119         } 
    120     }
    121     return 0;
    122 }
    View Code
  • 相关阅读:
    设计模式(2)——工厂模式详解
    直观理解梯度,以及偏导数、方向导数和法向量等
    如何编译和调试Python内核源码?
    VGG(2014),3x3卷积的胜利
    Network in Network(2013),1x1卷积与Global Average Pooling
    ZFNet(2013)及可视化的开端
    一文搞懂 deconvolution、transposed convolution、sub-­pixel or fractional convolution
    从AlexNet(2012)开始
    ImageNet主要网络benchmark对比
    仿射变换及其变换矩阵的理解
  • 原文地址:https://www.cnblogs.com/3200Pheathon/p/11618532.html
Copyright © 2020-2023  润新知