模板线段树

模板线段树

来至洛谷网站

 

 

如题,已知一个数列,你需要进行下面两种操作:

  1. 将某区间每一个数加上 kk。
  2. 求出某区间每一个数的和。

输入格式

第一行包含两个整数 n,,m,分别表示该数列数字的个数和操作的总个数。

第二行包含 nn个用空格分隔的整数,其中第 ii 个数字表示数列第 ii 项的初始值。

接下来 mm行每行包含 3 或 44个整数,表示一个操作,具体如下:

  1. 1 x y k:将区间 [x, y][x,y] 内每个数加上 k
  2. 2 x y:输出区间 [x, y][x,y] 内每个数的和。

输出格式

输出包含若干行整数,即为所有操作 2 的结果。

输入输出样例

 

如题,已知一个数列,你需要进行下面两种操作:

  1. 将某区间每一个数加上 kk。
  2. 求出某区间每一个数的和。

输入格式

第一行包含两个整数 n,,m,分别表示该数列数字的个数和操作的总个数。

第二行包含 nn个用空格分隔的整数,其中第 ii 个数字表示数列第 ii项的初始值。

接下来 m 行每行包含 3 或 4 个整数,表示一个操作,具体如下:

  1. 1 x y k:将区间 [x, y][x,y] 内每个数加上 k
  2. 2 x y:输出区间 [x, y][x,y] 内每个数的和。

输出格式

输出包含若干行整数,即为所有操作 2 的结果。

输入输出样例

 

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 long long ans;
 5 int add[100005];
 6 int n,m,x,y,k,Q,i,mid;
 7 int t=5;
 8 struct rec{
 9 int l,r;
10 long long dat;
11 }a[100005];
12 long long b[100005];
13 int Add(int p,int k)
14 {
15 add[p]+=k;
16 a[p].dat+=(a[p].r-a[p].l+1)*k;
17 }
18 void pushdown(int p)
19 {
20 if(add[p]==0)
21 return;
22 Add(p*2,add[p]);
23 Add(p*2+1,add[p]);
24 }
25 void build(int p,int L,int R)
26 {
27 a[p].l=L;
28 a[p].r=R;
29 if(L==R)
30 {
31 a[p].dat=b[L];
32 return;
33 }
34 mid=(L+R)/2;
35 build(p*2,L,mid);
36 build(p*2+1,mid+1,R);
37 a[p].dat=a[p*2].dat+a[p*2+1].dat;
38 t=t+1;
39 }
40 void change(int p,int L,int R,int k)
41 {
42 pushdown(p);
43 if((L<=a[p].l)&&(R>=a[p].r))
44 {
45 Add(p,k);
46 }
47 mid=(a[p].l+a[p].r)/2;
48 if(L<=mid)change(p*2,L,R,k);
49 if(R>mid)change(p*2+1,L,R,k);
50 }
51 long long ask(int p,int L,int R)
52 {
53 long long ans=0;
54 if((L<=a[p].l)&&(R>=a[p].r))
55 {
56 return a[p].dat;
57 }
58 pushdown(p);
59 mid=(a[p].l+a[p].r)/2;
60 if(L<=mid)ans+=ask(p*2,L,R);
61 if(R>mid)ans+=ask(p*2+1,L,R);
62 return ans;
63 }
64 int main()
65 {
66 cin>>n>>m;
67 
68 
69 for(i=1;i<=n;i++)
70 {
71 cin>>b[i];
72 
73 }
74 build(1,1,n);
75 
76 for(i=1;i<=m;i++)
77 {
78 cin>>Q;
79 if(Q==1)
80 {
81 cin>>x>>y>>k;
82 change(1,x,y,k);
83 }
84 else
85 {
86 
87 cin>>x>>y;
88 ask(1,x,y);
89 cout<<ans<<endl;
90 }
91 }
92 }
View Code

 

#include<iostream>
#include<cstring>
using namespace std;
long long ans;
int add[100005];
int n,m,x,y,k,Q,i,mid;
int t=5;
struct rec{
int l,r;
long long dat;
}a[100005];
long long b[100005];
int Add(int p,int k)
{
add[p]+=k;
a[p].dat+=(a[p].r-a[p].l+1)*k;
}
void pushdown(int p)
{
if(add[p]==0)
return;
Add(p*2,add[p]);
Add(p*2+1,add[p]);
}
void build(int p,int L,int R)
{
a[p].l=L;
a[p].r=R;
if(L==R)
{
a[p].dat=b[L];
return;
}
mid=(L+R)/2;
build(p*2,L,mid);
build(p*2+1,mid+1,R);
a[p].dat=a[p*2].dat+a[p*2+1].dat;
t=t+1;
}
void change(int p,int L,int R,int k)
{
pushdown(p);
if((L<=a[p].l)&&(R>=a[p].r))
{
Add(p,k);
}
mid=(a[p].l+a[p].r)/2;
if(L<=mid)change(p*2,L,R,k);
if(R>mid)change(p*2+1,L,R,k);
}
long long ask(int p,int L,int R)
{
long long ans=0;
if((L<=a[p].l)&&(R>=a[p].r))
{
return a[p].dat;
}
pushdown(p);
mid=(a[p].l+a[p].r)/2;
if(L<=mid)ans+=ask(p*2,L,R);
if(R>mid)ans+=ask(p*2+1,L,R);
return ans;
}
int main()
{
cin>>n>>m;


for(i=1;i<=n;i++)
{
cin>>b[i];

}
build(1,1,n);

for(i=1;i<=m;i++)
{
cin>>Q;
if(Q==1)
{
cin>>x>>y>>k;
change(1,x,y,k);
}
else
{

cin>>x>>y;
ask(1,x,y);
cout<<ans<<endl;
}
}
}

posted @ 2020-08-24 21:21  weidan01  阅读(145)  评论(0)    收藏  举报