zoukankan      html  css  js  c++  java
  • 洛谷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

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

    样例说明:

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

      1 #include<iostream>
      2 #include<cstdio>
      3 using namespace std;
      4 int n,m,p,judge,x,y,k;
      5 long long a[100007];
      6 long long read()
      7 {
      8     long long x=0,f=1;
      9     char ch=getchar();
     10     while(ch>'9'||ch<'0')
     11     {
     12         if(ch=='-')
     13             f=-1;
     14         ch=getchar();
     15     }
     16     while(ch>='0'&&ch<='9')
     17     {
     18         x=x*10+ch-'0';
     19         ch=getchar();
     20     }
     21     return x*f;
     22 }
     23 struct node
     24 {
     25     long long v,mul,add;
     26 } st[400007];
     27 void build(int root, int l, int r)
     28 {
     29     st[root].mul=1;
     30     st[root].add=0;
     31     if(l==r)
     32         st[root].v=a[l];
     33     else
     34     {
     35         int m=(l+r)/2;
     36         build(root*2, l, m);
     37         build(root*2+1, m+1, r);
     38         st[root].v=st[root*2].v+st[root*2+1].v;
     39     }
     40     st[root].v%=p;
     41     return ;
     42 }
     43 void pushdown(int root, int l, int r)
     44 {
     45     int m=(l+r)/2;
     46     st[root*2].v=(st[root*2].v*st[root].mul+st[root].add*(m-l+1))%p;
     47     st[root*2+1].v=(st[root*2+1].v*st[root].mul+st[root].add*(r-m))%p;
     48     st[root*2].mul=(st[root*2].mul*st[root].mul)%p;
     49     st[root*2+1].mul=(st[root*2+1].mul*st[root].mul)%p;
     50     st[root*2].add=(st[root*2].add*st[root].mul+st[root].add)%p;
     51     st[root*2+1].add=(st[root*2+1].add*st[root].mul+st[root].add)%p;
     52     st[root].mul=1;
     53     st[root].add=0;
     54     return ;
     55 }
     56 void up(int root,int stdl,int stdr,int l,int r,long long k)
     57 {
     58     if(r<stdl||stdr<l)
     59         return ;
     60     if(l<=stdl&&stdr<=r)
     61     {
     62         st[root].v=(st[root].v*k)%p;
     63         st[root].mul=(st[root].mul*k)%p;
     64         st[root].add=(st[root].add*k)%p;
     65         return ;
     66     }
     67     pushdown(root, stdl, stdr);
     68     int m=(stdl+stdr)/2;
     69     up(root*2,stdl,m,l,r,k);
     70     up(root*2+1,m+1,stdr,l,r,k);
     71     st[root].v=(st[root*2].v+st[root*2+1].v)%p;
     72     return ;
     73 }
     74 void date(int root,int stdl,int stdr,int l,int r,long long k)
     75 {
     76     if(r<stdl||stdr<l)
     77         return ;
     78     if(l<=stdl&&stdr<=r)
     79     {
     80         st[root].add=(st[root].add+k)%p;
     81         st[root].v=(st[root].v+k*(stdr-stdl+1))%p;
     82         return ;
     83     }
     84     pushdown(root,stdl,stdr);
     85     int m=(stdl+stdr)/2;
     86     date(root*2,stdl,m,l,r,k);
     87     date(root*2+1,m+1,stdr,l,r,k);
     88     st[root].v=(st[root*2].v+st[root*2+1].v)%p;
     89     return ;
     90 }
     91 long long query(int root,int stdl,int stdr,int l,int r)
     92 {
     93     if(r<stdl||stdr<l)
     94         return 0;
     95     if(l<=stdl&&stdr<=r)
     96         return st[root].v;
     97     pushdown(root,stdl,stdr);
     98     int m=(stdl+stdr)/2;
     99     return (query(root*2,stdl,m,l,r)+query(root*2+1,m+1,stdr,l,r))%p;
    100 }
    101 int main()
    102 {
    103     n=read(),m=read(),p=read();
    104     for(int i=1; i<=n; i++)
    105         a[i]=read();
    106     build(1,1,n);
    107     while(m--)
    108     {
    109         judge=read();
    110         if(judge==1)
    111         {
    112             x=read(),y=read(),k=read();
    113             up(1,1,n,x,y,k);
    114         }
    115         else if(judge==2)
    116         {
    117             x=read(),y=read(),k=read();
    118             date(1,1,n,x,y,k);
    119         }
    120         else
    121         {
    122             x=read(),y=read();
    123             printf("%lld
    ", query(1,1,n,x,y));
    124         }
    125     }
    126     return 0;
    127 }
    View Code
  • 相关阅读:
    pdflatex, xelatex, texstudio中文编码问题
    secure erase 时必须umount
    浪潮不能进bios解决过程
    ycsb-命令及参数-与生成的负载类型相关
    zt-Simple source policy routing
    oracle 分页查找数据
    前台调用后台的过程
    初识 java script
    java中的BigDecimal和String的相互转换
    一级缓存、二级缓存、延迟加载、hibernate session 域 pojo三种状态
  • 原文地址:https://www.cnblogs.com/liweilin/p/10198745.html
Copyright © 2011-2022 走看看