模板线段树
模板线段树
来至洛谷网站
如题,已知一个数列,你需要进行下面两种操作:
- 将某区间每一个数加上 kk。
- 求出某区间每一个数的和。
输入格式
第一行包含两个整数 n,,m,分别表示该数列数字的个数和操作的总个数。
第二行包含 nn个用空格分隔的整数,其中第 ii 个数字表示数列第 ii 项的初始值。
接下来 mm行每行包含 3 或 44个整数,表示一个操作,具体如下:
1 x y k:将区间 [x, y][x,y] 内每个数加上 k。2 x y:输出区间 [x, y][x,y] 内每个数的和。
输出格式
输出包含若干行整数,即为所有操作 2 的结果。
输入输出样例
如题,已知一个数列,你需要进行下面两种操作:
- 将某区间每一个数加上 kk。
- 求出某区间每一个数的和。
输入格式
第一行包含两个整数 n,,m,分别表示该数列数字的个数和操作的总个数。
第二行包含 nn个用空格分隔的整数,其中第 ii 个数字表示数列第 ii项的初始值。
接下来 m 行每行包含 3 或 4 个整数,表示一个操作,具体如下:
1 x y k:将区间 [x, y][x,y] 内每个数加上 k。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 }
#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;
}
}
}

浙公网安备 33010602011771号