线段树1 2
Posted -iris-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树1 2相关的知识,希望对你有一定的参考价值。
动态开点-指针
#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)<<‘
‘;
}
}
}
数组线段树
#include<iostream>
#include<cstdio>
using namespace std;
#define ls(x) x<<1
#define rs(x) x<<1|1
long long n,m;
long long a[500005];
struct node{
long long sum;
long long left,right;
long long tag;
}t[500005];
void build(long long root,long long lef,long long rig)
{
t[root].left =lef;
t[root].right =rig;
if(lef == rig)
{
t[root].sum =a[lef];
return;
}
long long mid=lef+rig>>1;
build(ls(root),lef,mid);
build(rs(root),mid+1,rig);
t[root].sum = t[ls(root)].sum + t[rs(root)].sum;
}
void spread(long long root)
{
if(t[root].tag)
{
// t[root].sum =t[root].sum +t[root].tag ;
t[ls(root)].sum +=t[root].tag * (t[ls(root)].right -t[ls(root)].left+1 );
t[rs(root)].sum +=t[root].tag * (t[rs(root)].right -t[rs(root)].left+1 );
t[rs(root)].tag +=t[root].tag;
t[ls(root)].tag +=t[root].tag;
t[root].tag =0;
}
}
void change(long long r,long long lef,long long rig,long long dis)
{
if(lef<=t[r].left && rig>=t[r].right )
{
t[r].sum += dis *(t[r].right -t[r].left +1 );
t[r].tag +=dis;
return ;
}
spread(r);
long long mid=t[r].left +t[r].right>>1;
if(lef<=mid) change(ls(r),lef,rig,dis);
if(rig>mid) change(rs(r),lef,rig,dis);
t[r].sum =t[ls(r)].sum +t[rs(r)].sum;
}
long long ask(long long r,long long lef,long long rig)
{
if(lef<=t[r].left &&rig>=t[r].right ) return t[r].sum ;
spread(r);
long long ans=0;
long long mid=t[r].left +t[r].right>>1;
if(lef<=mid) ans+=ask(ls(r),lef,rig);
if(rig>mid) ans+=ask(rs(r),lef,rig);
return ans;
}
int main()
{
long long x,y,z,k;
ios_base::sync_with_stdio(false);
cout.tie(NULL);
cin>>n>>m;
for(long long i=1;i<=n;i++)
cin>>a[i];
build(1,1,n);
for(long long i=1;i<=m;i++)
{
cin>>k;
if(k==1)
{
cin>>x>>y>>z;
change(1,x,y,z);
}
if(k==2)
{
cin>>x>>y;
cout<<ask(1,x,y)<<‘
‘;
}
}
线段树2
#include<iostream>
#include<cstdio>
using namespace std;
const long long k=5e5+5;
long long a[k];
long long p;
struct Segment{
long long l,r;
long long sum;
long long tag;
long long tag_x;
Segment *lef,*rig;
Segment(const long long L,const long long R ) : l(L),r(R),sum(0),tag(0),tag_x(1),lef(NULL),rig(NULL) {}
inline void maketage(const long long mul,const long long add)
{
sum=(mul *sum)%p + ((r-l+1)*add)%p;
sum%=p;
tag_x*=mul;
tag_x%=p;
tag=(tag * mul +add)%p;
}
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 && tag_x == 1) return;
else {
lef->maketage(tag_x,tag);
rig->maketage(tag_x,tag);
tag=0;
tag_x=1;
}
}
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){
maketage(1,val);
}
else {
if(Out(L,R)) return ;
else{
spread();
lef->change(L,R,val);
rig->change(L,R,val);
sum=lef->sum+rig->sum;
sum%=p;
}
}
}
void change_x(long long L,long long R,long long val)
{
if(L<=l && r<=R){
maketage(val,0);
}
else{
if(Out(L,R)) return ;
else{
spread();
lef->change_x(L,R,val);
rig->change_x(L,R,val);
sum=lef->sum + rig->sum ;
sum%=p;
}
}
}
long long ask(long long L,long long R)
{
if(L<=l && r<=R) return sum%p;
else {
if(Out(L,R)) return 0;
else{
spread();
return (lef->ask(L,R)%p) + (rig->ask(L,R)%p);
}
}
}
};
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>>p;
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==2){
cin>>g;
root->change(y,z,g);
}
if(x== 3) {
cout<<root->ask(y,z)%p<<‘
‘;
}
if(x== 1)
{
cin>>g;
root->change_x(y,z,g);
}
}
}
end
以上是关于线段树1 2的主要内容,如果未能解决你的问题,请参考以下文章