zoukankan      html  css  js  c++  java
  • 【原创】洛谷 LUOGU P3373 【模板】线段树2

    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 // LUOGU 3373 【模板】线段树2 
      2 // 2017.7.20 20:52
      3 #include<bits/stdc++.h>
      4 #define INF 0x3fffffff
      5 #define MAXN 100000
      6 #define MAXT MAXN*4
      7 using namespace std;
      8 typedef long long ll;
      9 int N,M,topt=0;
     10 ll P,a[MAXN+2];
     11 struct sgt_node{
     12     int lc,rc;
     13     ll sum,pls,mul;
     14     sgt_node(){pls=0,mul=INF;}
     15 }sgt[MAXT+2];
     16 int getint(){
     17     char ch='*';
     18     while(!isdigit(ch=getchar()));
     19     int num=ch-'0';
     20     while(isdigit(ch=getchar()))num=num*10+ch-'0';
     21     return num;
     22 }
     23 ll getll(){
     24     char ch='*';
     25     while(!isdigit(ch=getchar()));
     26     ll num=ch-'0';
     27     while(isdigit(ch=getchar()))num=num*10+ch-'0';
     28     return num;
     29 }
     30 #define lch sgt[now].lc
     31 #define rch sgt[now].rc
     32 #define smid ((l+r)>>1)
     33 void update(int now){
     34     sgt[now].sum=(sgt[lch].sum+sgt[rch].sum)%P;
     35 }
     36 void set_mul(int now,ll v){
     37     sgt[now].sum=(sgt[now].sum*v)%P;
     38     if(sgt[now].mul==INF)sgt[now].mul=v%P;
     39     else sgt[now].mul=(sgt[now].mul*v)%P;  // 必须为乘法!!!
     40     sgt[now].pls=(sgt[now].pls*v)%P;
     41 }
     42 void set_pls(int now,int l,int r,ll v){
     43     sgt[now].sum=(sgt[now].sum+v*(r-l+1))%P;
     44     sgt[now].pls=(sgt[now].pls+v)%P;
     45 }
     46 void push_down(int now,int l,int r){
     47     if(sgt[now].mul!=INF){
     48         set_mul(lch,sgt[now].mul);
     49         set_mul(rch,sgt[now].mul);
     50         sgt[now].mul=INF;
     51     }
     52     if(sgt[now].pls){
     53         set_pls(lch,l,smid,sgt[now].pls);
     54         set_pls(rch,smid+1,r,sgt[now].pls);
     55         sgt[now].pls=0;
     56     }
     57 }
     58 void Build_sgt(int &now,int l,int r){
     59     now=++topt;
     60     if(l==r){
     61         sgt[now].sum=a[l];
     62         return;
     63     }
     64     Build_sgt(lch,l,smid);
     65     Build_sgt(rch,smid+1,r);
     66     update(now);
     67 }
     68 ll Query_sgt(int now,int l,int r,int qx,int qy){
     69     if(l==qx&&r==qy)return sgt[now].sum;
     70     push_down(now,l,r);
     71     if(qy<=smid)return Query_sgt(lch,l,smid,qx,qy);
     72     if(qx>smid)return Query_sgt(rch,smid+1,r,qx,qy);
     73     return Query_sgt(lch,l,smid,qx,smid)+Query_sgt(rch,smid+1,r,smid+1,qy);
     74 }
     75 void Region_mul(int now,int l,int r,int x,int y,ll v){
     76     if(l==x&&r==y){
     77         set_mul(now,v);
     78         return;
     79     }
     80     push_down(now,l,r);
     81     if(y<=smid)Region_mul(lch,l,smid,x,y,v);
     82     else if(x>smid)Region_mul(rch,smid+1,r,x,y,v);
     83     else{
     84         Region_mul(lch,l,smid,x,smid,v);
     85         Region_mul(rch,smid+1,r,smid+1,y,v);
     86     }
     87     update(now);
     88 }
     89 void Region_pls(int now,int l,int r,int x,int y,ll v){
     90     if(l==x&&r==y){
     91         set_pls(now,l,r,v);
     92         return;
     93     }
     94     push_down(now,l,r);
     95     if(y<=smid)Region_pls(lch,l,smid,x,y,v);
     96     else if(x>smid)Region_pls(rch,smid+1,r,x,y,v);
     97     else{
     98         Region_pls(lch,l,smid,x,smid,v);
     99         Region_pls(rch,smid+1,r,smid+1,y,v);
    100     }
    101     update(now);
    102 }
    103 int main(){
    104     N=getint(),M=getint(),P=getll();
    105     for(int i=1;i<=N;i++)
    106         a[i]=getll();
    107     int root=0;
    108     Build_sgt(root,1,N);
    109     int op,x,y;
    110     ll k;
    111     for(int i=1;i<=M;i++){
    112         op=getint();
    113         switch(op){
    114             case 1:
    115                 x=getint(),y=getint(),k=getll();
    116                 Region_mul(1,1,N,x,y,k);
    117                 break;
    118             case 2:
    119                 x=getint(),y=getint(),k=getll();
    120                 Region_pls(1,1,N,x,y,k);
    121                 break;
    122             case 3:
    123                 x=getint(),y=getint();
    124                 printf("%lld
    ",Query_sgt(1,1,N,x,y)%P);
    125                 break;
    126         }
    127     }    
    128     return 0;
    129 }
  • 相关阅读:
    [Python] Read and Parse Files in Python
    [React] Write Compound Components
    [Python] Reuse Code in Multiple Projects with Python Modules
    [Parcel] Bundle a React App with Parcel
    [Javascript] Specify this using .call() or .apply()
    [Javascript] this in Function Calls
    [Python] Create a Log for your Python application
    [Python] Create Unique Unordered Collections in Python with Set
    [Python] Manipulate Data with Dictionaries in Python
    SVN:常用命令
  • 原文地址:https://www.cnblogs.com/darkleafin/p/7214473.html
Copyright © 2011-2022 走看看