zoukankan      html  css  js  c++  java
  • 洛谷P2023 [AHOI2009]维护序列 线段树

    洛谷P2023 [AHOI2009]维护序列

    线段树 带乘法标记 和 加法标记
    处理两个标记时记得要两个标记之间互不影响,
    如果有影响,则要改变一下

    我们一律先处理乘法标记 在处理加法标记
    如果已经有了加法标记 又来了一个乘法标记
    那么加法 标记也要乘 否则就不能做到强制先后了
    这样就能保证标记之间互不影响

      1 #include <cstdio>
      2 #include <cmath>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <string>
      6 #include <algorithm>
      7 #include <iostream> 
      8 #include <iomanip>
      9 #define ll long long  
     10 using namespace std ; 
     11 
     12 const int maxn = 100011 ; 
     13 
     14 struct node{
     15     int l,r ;
     16     ll sum,ADD,MUL ; 
     17 }tree[maxn*4];
     18 int n,Q ; 
     19 ll ans,v,mod ; 
     20 int a[maxn] ; 
     21 
     22 inline ll read() 
     23 {
     24     char ch = getchar() ; 
     25     ll  x=0,f=1 ; 
     26     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ; } 
     27     while(ch>='0'&&ch<='9') { x = x*10+ch-48 ; ch = getchar() ; } 
     28     return x * f ; 
     29 }
     30 
     31 inline void write(ll x) 
     32 {
     33     if(x<0) x = -x,putchar('-') ; 
     34     if(x>9) write(x/10) ; 
     35     putchar(x % 10 + 48 ) ;    
     36 }  
     37 
     38 inline void writeln(ll x )  { write(x) ; putchar('
    ') ; }  
     39 inline void pushup(int root) 
     40 {
     41     tree[root].sum = ( tree[root<<1].sum + tree[root<<1|1].sum ) %mod ; 
     42 }
     43 
     44 inline void build(int root,int l,int r) 
     45 {
     46     tree[root].l = l ;  tree[root].r = r ;  
     47     tree[root].MUL = 1 ;tree[root].ADD = 0 ; 
     48     if(l==r) 
     49     {
     50         tree[root].sum = a[ l ] ;
     51         return ;  
     52     }
     53     int mid = (l+r) /2 ; 
     54     build(root<<1,l,mid) ; 
     55     build(root<<1|1,mid+1,r) ; 
     56     pushup(root) ; 
     57 }
     58 
     59 inline void pushdown(int root) 
     60 {
     61     if(tree[root].MUL==1&&tree[root].ADD==0) return ; 
     62     tree[root<<1].ADD =  ( tree[root<<1].ADD * tree[root].MUL +tree[root].ADD ) %mod ; 
     63     tree[root<<1|1].ADD = (tree[root<<1|1].ADD*tree[root].MUL +tree[root].ADD ) %mod ; 
     64     
     65     tree[root<<1].MUL = tree[root<<1].MUL * tree[root].MUL % mod ; 
     66     tree[root<<1|1].MUL = tree[root<<1|1].MUL*tree[root].MUL % mod ; 
     67     
     68     tree[root<<1].sum=( tree[root<<1].sum * tree[root].MUL + tree[root].ADD *(tree[root<<1].r-tree[root<<1].l+1)  ) % mod;
     69     tree[root<<1|1].sum=( tree[root<<1|1].sum*tree[root].MUL + tree[root].ADD *(tree[root<<1|1].r-tree[root<<1|1].l+1)  ) % mod;
     70     tree[root].MUL = 1 ; 
     71     tree[root].ADD = 0 ;  
     72 }
     73 
     74 inline void updata(int root,int l,int r,ll mul,ll add) 
     75 {
     76     if(tree[root].l==l&&tree[root].r==r) 
     77     {
     78         tree[root].ADD = (  tree[root].ADD * mul + add )  % mod ; 
     79         tree[root].MUL = tree[root].MUL * mul % mod ; 
     80         tree[root].sum = ( tree[root].sum*mul  + (tree[root].r-tree[root].l+1) * add ) %mod ;  
     81         return ; 
     82     }
     83     pushdown(root) ; 
     84     int mid = (tree[root].l + tree[root].r) /2 ; 
     85     if( r<=mid ) updata(root<<1,l,r,mul,add) ; 
     86     else if( l>mid )  updata(root<<1|1,l,r,mul,add) ; 
     87     else 
     88     {
     89         updata(root<<1,l,mid,mul,add) ; 
     90         updata(root<<1|1,mid+1,r,mul,add) ; 
     91     }
     92     pushup(root) ; 
     93 }
     94 
     95 inline ll query(int root,int l,int r) 
     96 {
     97     if(tree[root].l==l&&tree[root].r==r) 
     98         return tree[root].sum ; 
     99     pushdown(root) ; 
    100     
    101     int mid = (tree[root].l + tree[root].r) /2 ; 
    102     if( r<=mid ) return query(root<<1,l,r)  ; 
    103     if( l>mid )  return query(root<<1|1,l,r) ; 
    104     ll ans = 0 ; 
    105     ans = (ans+query(root<<1,l,mid)) %mod ; 
    106     ans = (ans+query(root<<1|1,mid+1,r)) %mod ; 
    107     return ans ;     
    108 }
    109 
    110 int main() 
    111 {
    112     n = read() ; mod = read() ; 
    113     for(int i=1;i<=n;i++) 
    114         a[ i ] = read(),a[ i ] %=mod ; 
    115     build(1,1,n) ; 
    116     Q = read() ; 
    117     int type,l,r ; 
    118     for(int i=1;i<=Q;i++) 
    119     {
    120         type = read() ; l = read() ;  r = read() ; 
    121         if(type==1) 
    122         {
    123             v = read() ;  v%=mod ; 
    124             updata(1,l,r,v,0) ;  
    125         }
    126         if(type==2) 
    127         {
    128             v = read() ; v%=mod ; 
    129             updata(1,l,r,1,v) ; 
    130         } 
    131         if(type==3) 
    132         {
    133             ans = query(1,l,r) %mod ; 
    134             writeln( ans ) ; 
    135         }
    136     } 
    137     
    138      return 0 ; 
    139 }
  • 相关阅读:
    c#大文件上传解决方案支持分片断点上传
    css精灵动画
    文字游戏
    利用myeclipse配置数据库连接池
    python 简单的txt文件读写
    数据库连接池配置
    hdu 1030 Delta-wave
    java jdbc sqlhelper
    js实现页面的自动读秒跳转
    购物车模块
  • 原文地址:https://www.cnblogs.com/third2333/p/7095137.html
Copyright © 2011-2022 走看看