ACの手段———线段树
线段树
#include<bits/stdc++.h>
using namespace std;
int a[1000010],n,m;
struct xd_tree
{
int l,r,sum;
};
xd_tree tree[4000010];
#define flzc (root<<1)
#define fryc (root<<1|1)
void build(int root,int lc,int rc)
{
tree[root].l=lc;
tree[root].r=rc;
if(lc==rc)
{
tree[root].sum=a[lc];
return ;
}
int mid=(lc+rc)>>1;
build(flzc,lc,mid);
build(fryc,mid+1,rc);
tree[root].sum=tree[flzc].sum+tree[fryc].sum;
}
void add(int root,int x,int val)
{
if(tree[root].l==tree[root].r)
{
tree[root].sum+=val;
return ;
}
int mid=(tree[root].l+tree[root].r)>>1;
if(x<=mid)
{
add(flzc,x,val);
}
else
{
add(fryc,x,val);
}
tree[root].sum=tree[flzc].sum+tree[fryc].sum;
}
int find(int root,int fl,int fr)
{
if(tree[root].l==fl&&tree[root].r==fr)
{
return tree[root].sum;
}
int mid=(tree[root].l+tree[root].r)>>1;
if(fr<=mid)
{
return find(flzc,fl,fr);
}
else if(fl>mid)
{
return find(fryc,fl,fr);
}
return find(flzc,fl,mid)+find(fryc,mid+1,fr);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
if(n>1)
{
build(1,1,n);
}
cin>>m;
string s;
for(int i=1;i<=m;i++)
{
cin>>s;
if(s=="ADD")
{
int x,y;
cin>>x>>y;
add(1,x,y);
}
if(s=="SUM")
{
int l,r;
cin>>l>>r;
cout<<find(1,l,r)<<endl;
}
}
return 0;
}
线段树+延迟标记
#include<bits/stdc++.h>
using namespace std;
long long a[100010];
struct st_t
{
long long l=0,r=0,sum=0,tag=0;
};
st_t t[400010];
long long n,m;
#define ls (ro<<1)
#define rs (ro<<1|1)
void build(long long ro,long long lc,long long rc)
{
t[ro].l=lc;
t[ro].r=rc;
if(lc==rc)
{
t[ro].sum=a[lc];
return ;
}
long long mid=(lc+rc)>>1;
build(ls,lc,mid);
build(rs,mid+1,rc);
t[ro].sum=t[ls].sum+t[rs].sum;
}
void pud(long long ro)
{
if(t[ro].tag!=0)
{
t[ls].tag+=t[ro].tag;
t[rs].tag+=t[ro].tag;
t[ls].sum+=t[ro].tag*(t[ls].r-t[ls].l+1);
t[rs].sum+=t[ro].tag*(t[rs].r-t[rs].l+1);
t[ro].tag=0;
return ;
}
}
void add(long long ro,long long fl,long long fr,long long v)
{
if(t[ro].l>fr||t[ro].r<fl)
{
return ;
}
if(t[ro].l>=fl&&t[ro].r<=fr)
{
t[ro].tag+=v;
t[ro].sum+=(t[ro].r-t[ro].l+1)*v;
return ;
}
pud(ro);
add(ls,fl,fr,v);
add(rs,fl,fr,v);
t[ro].sum=t[ls].sum+t[rs].sum;
}
long long find(long long ro,long long fl,long long fr)
{
if(t[ro].l>=fl&&t[ro].r<=fr)
{
return t[ro].sum;
}
if(t[ro].l>fr||t[ro].r<fl)
{
return 0;
}
pud(ro);
return find(ls,fl,fr)+find(rs,fl,fr);
}
int main()
{
cin>>n;
for(long long i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,1,n);
cin>>m;
for(long long i=1;i<=m;i++)
{
string s;
cin>>s;
if(s=="ADD")
{
long long l,r,x;
cin>>l>>r>>x;
add(1,l,r,x);
}
if(s=="SUM")
{
long long l,r;
cin>>l>>r;
cout<<find(1,l,r)<<endl;
}
}
return 0;
}
线段树+可持久化
例题:P3919 【模板】可持久化线段树 1(可持久化数组)
#include<bits/stdc++.h>
using namespace std;
int a[1000010];
struct jade
{
int l,r,v;
}t[30000010];
int id,rt[1000010];
int init(int x)
{
id++;
t[id]=t[x];
return id;
}
int build(int ro,int l,int r)
{
id++;
ro=id;
if(l==r)
{
t[ro].v=a[l];
return id;
}
int mid=(l+r)>>1;
t[ro].l=build(t[ro].l,l,mid);
t[ro].r=build(t[ro].r,mid+1,r);
return ro;
}
int add(int ro,int l,int r,int p,int v)
{
ro=init(ro);
if(l==r)
{
t[ro].v=v;
return ro;
}
int mid=(l+r)>>1;
if(p<=mid)
{
t[ro].l=add(t[ro].l,l,mid,p,v);
}
else
{
t[ro].r=add(t[ro].r,mid+1,r,p,v);
}
return ro;
}
int find(int ro,int l,int r,int p)
{
if(l==r)
{
return t[ro].v;
}
int mid=(l+r)>>1;
if(p<=mid)
{
return find(t[ro].l,l,mid,p);
}
else
{
return find(t[ro].r,mid+1,r,p);
}
}
int main()
{
int n,q;
cin>>n>>q;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
rt[0]=build(0,1,n);
for(int i=1;i<=q;i++)
{
int v,op;
scanf("%d%d",&v,&op);
if(op==1)
{
int p,c;
scanf("%d%d", &p, &c);
rt[i]=add(rt[v],1,n,p,c);
}
else
{
int p;
scanf("%d", &p);
printf("%d\n",find(rt[v],1,n,p));
rt[i]=rt[v];
}
}
return 0;
}
感谢肝硬化画的jade seek
如图:

以下是签名
${\scr {jade }}$ ${\scr {seek }}$
本文来自博客园,作者:BIxuan—玉寻,转载请注明原文链接:https://www.cnblogs.com/zhangyuxun100219/p/18897610

浙公网安备 33010602011771号