zoukankan      html  css  js  c++  java
  • 洛谷 3373 线段树练习

    题目描述

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

    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

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

    样例说明:

    故输出应为17、2(40 mod 38=2)

    做法:因为数据的关系,需要打lazy标记,考虑将加法和乘法的分开打,乘法优先更新可以保证不会错(复习线段树)。

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <cstring>
      4 #define LL long long
      5 #define rep(i,a,b) for(int i=a;i<=b;i++)
      6 #define N 100007
      7 using namespace std;
      8 int n,m;
      9 LL mo,a[N],mul[N*4],pul[N*4],t[N*4],ans=0;
     10 
     11 inline LL Read(){
     12     LL s=0;
     13     int zf=1;
     14     char ch=getchar();
     15     for(;(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
     16     if (ch=='-') zf=-1,ch=getchar();
     17     for(;ch>='0'&&ch<='9';s=s*10+ch-'0',ch=getchar());
     18     return s*zf;
     19 }
     20 
     21 inline void Build(int p,int l,int r){
     22     mul[p]=1;
     23     pul[p]=0;
     24     if (l==r){ t[p]=a[l]%mo; return; }
     25     int mid=(l+r)>>1;
     26     Build(p<<1,l,mid);
     27     Build(p<<1|1,mid+1,r);
     28     t[p]=(t[p<<1]+t[p<<1|1])%mo;
     29 }
     30 
     31 inline void Pushdown(int p,int l,int r){
     32     int mid=(l+r)/2;
     33     t[p<<1]=(t[p<<1]*mul[p]+pul[p]*(mid-l+1))%mo;
     34     t[p<<1|1]=(t[p<<1|1]*mul[p]+pul[p]*(r-mid))%mo;
     35     mul[p<<1]=(mul[p<<1]*mul[p])%mo;
     36     mul[p<<1|1]=(mul[p<<1|1]*mul[p])%mo;
     37     pul[p<<1]=(pul[p<<1]*mul[p]+pul[p])%mo;
     38     pul[p<<1|1]=(pul[p<<1|1]*mul[p]+pul[p])%mo;
     39     pul[p]=0;
     40     mul[p]=1;
     41 }
     42 
     43 inline void Upmul(int p,int l,int r,int ax,int ay,LL num){
     44     if(l>ay||r<ax) return;
     45     if(ax<=l&&r<=ay){
     46         t[p]=(t[p]*num)%mo;
     47         mul[p]=(mul[p]*num)%mo;
     48         pul[p]=(pul[p]*num)%mo;
     49         return;
     50     }
     51     Pushdown(p,l,r);
     52     int mid=(l+r)>>1;
     53     Upmul(p<<1,l,mid,ax,ay,num);
     54     Upmul(p<<1|1,mid+1,r,ax,ay,num);
     55     t[p]=(t[p<<1]+t[p<<1|1])%mo;
     56 }
     57 
     58 inline void Uppul(int p,int l,int r,int ax,int ay,LL num){
     59     if(l>ay||r<ax) return;
     60     if(ax<=l&&r<=ay){
     61         pul[p]=(pul[p]+num)%mo;
     62         t[p]=(t[p]+num*(r-l+1))%mo;
     63         return;
     64     }
     65     Pushdown(p,l,r);
     66     int mid=(l+r)>>1;
     67     Uppul(p<<1,l,mid,ax,ay,num);
     68     Uppul(p<<1|1,mid+1,r,ax,ay,num);
     69     t[p]=(t[p<<1]+t[p<<1|1])%mo;
     70 
     71 }
     72 
     73 inline void Count(int p,int l,int r,int ax,int ay){
     74     if (l>ay||r<ax) return;
     75     if (ax<=l&&r<=ay){
     76         ans=(ans+t[p])%mo;
     77         return;
     78     }
     79     int mid=(l+r)>>1;
     80     Pushdown(p,l,r);
     81     Count(p<<1,l,mid,ax,ay);
     82     Count(p<<1|1,mid+1,r,ax,ay);
     83 }
     84 
     85 int main(){
     86     n=Read(),m=Read(),mo=Read();
     87     rep(i,1,n) a[i]=Read();
     88     Build(1,1,n);
     89     int ain,x,y,k;
     90     for(;m--;){
     91         ain=Read();
     92         if(ain==1){
     93             x=Read(),y=Read(),k=Read();
     94             Upmul(1,1,n,x,y,k);
     95         }
     96         if(ain==2){
     97             x=Read(),y=Read(),k=Read();
     98             Uppul(1,1,n,x,y,k);
     99         }
    100         if(ain==3){
    101             x=Read(),y=Read();
    102             ans=0;
    103             Count(1,1,n,x,y);
    104             printf("%lld
    ",ans);
    105         }
    106     } 
    107 }
    View Code
  • 相关阅读:
    GTD时间管理(1)---捕获搜集
    ios面试总结-
    Swift入门篇-结构体
    Swift入门篇-闭包和函数
    swift入门篇-函数
    Swift入门篇-集合
    Swift入门篇-循环语句
    Swift入门篇-基本类型(3)
    Swift入门篇-基本类型(2)
    Swift入门篇-基本类型(1)
  • 原文地址:https://www.cnblogs.com/traveller-ly/p/9594285.html
Copyright © 2011-2022 走看看