码迷,mamicode.com
首页 > 其他好文 > 详细

线段树 1 2

时间:2020-07-05 17:00:43      阅读:58      评论:0      收藏:0      [点我收藏+]

标签:null   etag   线段树   mes   bool   str   efi   node   else   

不多bb

直接代码

#include<iostream>
#include<cstdio>

using namespace std;

const long long  k=5e5+5;

long long  a[k];

struct Segment{
    long long  l,r;
    long long  sum;
    long long  tag;
    Segment *lef,*rig;
    
    Segment(const long long  L,const long long  R ) : l(L),r(R),sum(0),tag(0),lef(NULL),rig(NULL) {} 
    
    inline void maketag(const long long  val){
        sum+=val*(r-l+1);
        tag+=val;
    }
    
    void spread()
    {
        long long  mid=(l+r)>>1;
        if(lef == NULL) lef=new Segment(l,mid);
        if(rig == NULL) rig =new Segment(mid+1,r);
        if(tag==0) return;
        else {
            lef->maketag(tag);
            rig->maketag(tag);
            tag=0;
        }
    }    

    inline bool Out(const long long  L,const long long  R) { return (R<l || r<L ) ;}

    void change(long long  L,long long  R,long long  val)
    {
        if(L<=l && r<=R){
            maketag(val);
        }
        else {
            if(Out(L,R)) return ;
            else{
            spread();
            lef->change(L,R,val);
            rig->change(L,R,val);
            sum=lef->sum+rig->sum;
            } 
            
        }
    }
    
    
    long long  ask(long long  L,long long  R)
    {
        if(L<=l && r<=R) return sum;
        else {
            if(Out(L,R)) return 0;
            else{
            spread();
            return lef->ask(L,R)+rig->ask(L,R);
            
            } 
            
        }
    }
    
};

Segment *root;

int  main(void)
{
    long long  n,m,q;
    
    ios_base::sync_with_stdio(false);
    cout.tie(NULL);
    cin.tie(NULL);
    
    cin>>n>>m;
    
    root=new Segment(1,n);
    
    for(long long  i=1;i<=n;i++)
    {
        cin>>q;
        root->change(i,i,q);
    }
    
    
    
    for(long long  i=1;i<=m;i++)
    {
        long long  x,y,z,g;
        cin>>x>>y>>z;
        
        if(x==1){
            cin>>g;
            root->change(y,z,g);
        }
        else {
            cout<<root->ask(y,z)<<\n;
        }
    }
}

 

下面是数组线段树

 

  1 #include<iostream>
  2 #include<cstdio>
  3 
  4 using namespace std;
  5 
  6 #define ls(x) x<<1
  7 #define rs(x) x<<1|1
  8 
  9 long long n,m;
 10 long long a[500005];
 11 
 12 struct node{
 13     long long sum;
 14     long long left,right;
 15     long long tag;
 16 }t[500005];
 17 
 18 void build(long long root,long long lef,long long rig)
 19 {
 20     t[root].left =lef;
 21     t[root].right =rig;
 22     if(lef == rig)
 23     {
 24         t[root].sum =a[lef];
 25         return;
 26     }
 27     long long mid=lef+rig>>1;
 28     build(ls(root),lef,mid);
 29     build(rs(root),mid+1,rig);
 30     t[root].sum = t[ls(root)].sum + t[rs(root)].sum; 
 31 }
 32 
 33 void spread(long long root)
 34 {
 35     if(t[root].tag)
 36     {
 37 //        t[root].sum =t[root].sum +t[root].tag ;
 38         t[ls(root)].sum +=t[root].tag * (t[ls(root)].right -t[ls(root)].left+1 );
 39         t[rs(root)].sum +=t[root].tag * (t[rs(root)].right -t[rs(root)].left+1 );
 40         t[rs(root)].tag +=t[root].tag;
 41         t[ls(root)].tag +=t[root].tag;
 42         t[root].tag =0;
 43         
 44     }
 45 }
 46 
 47 void change(long long r,long long lef,long long rig,long long dis)
 48 {
 49     if(lef<=t[r].left && rig>=t[r].right )
 50     {
 51         t[r].sum += dis *(t[r].right -t[r].left +1 );
 52         t[r].tag +=dis;
 53         return ;
 54     }
 55     spread(r);
 56     long long mid=t[r].left +t[r].right>>1;
 57     if(lef<=mid) change(ls(r),lef,rig,dis);
 58     if(rig>mid) change(rs(r),lef,rig,dis);
 59     t[r].sum =t[ls(r)].sum +t[rs(r)].sum;
 60     
 61 }
 62 
 63 long long ask(long long r,long long lef,long long rig)
 64 {
 65     if(lef<=t[r].left &&rig>=t[r].right ) return t[r].sum ;
 66     spread(r);
 67     long long ans=0;
 68     long long mid=t[r].left +t[r].right>>1;
 69     if(lef<=mid) ans+=ask(ls(r),lef,rig);
 70     if(rig>mid) ans+=ask(rs(r),lef,rig);
 71     return ans;
 72     
 73 }
 74 
 75 int main()
 76 {
 77     long long x,y,z,k;
 78     
 79     ios_base::sync_with_stdio(false);
 80     cout.tie(NULL);
 81     
 82     cin>>n>>m;
 83     
 84     for(long long i=1;i<=n;i++)
 85     cin>>a[i];
 86     
 87     build(1,1,n);
 88     
 89     for(long long i=1;i<=m;i++)
 90     {
 91         cin>>k;
 92         if(k==1)
 93         {
 94             cin>>x>>y>>z;
 95             change(1,x,y,z);
 96         }
 97         if(k==2)
 98         {
 99             cin>>x>>y;
100             cout<<ask(1,x,y)<<\n;
101         }
102     }

 

 

最后是 线段树2

  1 #include<iostream>
  2 #include<cstdio>
  3 
  4 using namespace std;
  5 
  6 const long long  k=5e5+5;
  7 
  8 long long  a[k];
  9 long long p;
 10 
 11 struct Segment{
 12     long long  l,r;
 13     long long  sum;
 14     long long  tag;
 15     long long tag_x;
 16     Segment *lef,*rig;
 17     
 18     Segment(const long long  L,const long long  R ) : l(L),r(R),sum(0),tag(0),tag_x(1),lef(NULL),rig(NULL) {} 
 19     
 20     inline void maketage(const long long mul,const long long add) 
 21     {
 22         sum=(mul *sum)%p + ((r-l+1)*add)%p;
 23         sum%=p;
 24         tag_x*=mul;
 25         tag_x%=p;
 26         tag=(tag * mul +add)%p;
 27         
 28     }
 29     
 30     void spread()
 31     {
 32         long long  mid=(l+r)>>1;
 33         
 34         if(lef == NULL) lef=new Segment(l,mid);
 35         if(rig == NULL) rig =new Segment(mid+1,r);
 36     
 37         if(tag==0 && tag_x == 1) return;
 38         else {
 39             lef->maketage(tag_x,tag);
 40             rig->maketage(tag_x,tag);
 41             tag=0;
 42             tag_x=1;
 43         }
 44     }    
 45 
 46     inline bool Out(const long long  L,const long long  R) { return (R<l || r<L ) ;}
 47 
 48     void change(long long  L,long long  R,long long  val)
 49     {
 50         if(L<=l && r<=R){
 51             maketage(1,val);
 52         }
 53         else {
 54             if(Out(L,R)) return ;
 55             else{
 56             spread();
 57             lef->change(L,R,val);
 58             rig->change(L,R,val);
 59             sum=lef->sum+rig->sum;
 60             sum%=p;
 61             } 
 62             
 63         }
 64     }
 65     
 66     void change_x(long long  L,long long  R,long long  val)
 67     {
 68         if(L<=l && r<=R){
 69             maketage(val,0);
 70         }
 71         else{
 72             if(Out(L,R)) return ;
 73             else{
 74                 spread();
 75                 lef->change_x(L,R,val);
 76                 rig->change_x(L,R,val);
 77                 sum=lef->sum + rig->sum ; 
 78                 sum%=p; 
 79             }
 80         }
 81     }
 82     
 83     
 84     long long  ask(long long  L,long long  R)
 85     {
 86         if(L<=l && r<=R) return sum%p;
 87         
 88         else {
 89             
 90             if(Out(L,R)) return 0;
 91             
 92             else{
 93             
 94             spread();
 95             
 96             return (lef->ask(L,R)%p) + (rig->ask(L,R)%p);
 97             
 98             } 
 99             
100         }
101     }
102     
103 };
104 
105 Segment *root;
106 
107 int  main(void)
108 {
109     long long  n,m,q;
110     
111     ios_base::sync_with_stdio(false);
112     cout.tie(NULL);
113     cin.tie(NULL);
114     
115     cin>>n>>m>>p;
116     
117     root=new Segment(1,n);
118     
119     for(long long  i=1;i<=n;i++)
120     {
121         cin>>q;
122         root->change(i,i,q);
123     }
124     
125     
126     
127     for(long long  i=1;i<=m;i++)
128     {
129         long long  x,y,z,g;
130         cin>>x>>y>>z;
131         
132         if(x==2){
133             cin>>g;
134             root->change(y,z,g);
135         }
136         if(x== 3) {
137             cout<<root->ask(y,z)%p<<\n;
138         }
139         if(x== 1)
140         {
141             cin>>g;
142             root->change_x(y,z,g); 
143         }
144     }
145 }

 

 

-end-

线段树 1 2

标签:null   etag   线段树   mes   bool   str   efi   node   else   

原文地址:https://www.cnblogs.com/-Iris-/p/13246518.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!