您的位置:首页 > 其它

[线段树] poj3468 A Simple Problem with Integers

2015-07-29 14:58 288 查看
重新把以前的线段树内容写了一遍,线段树的熟悉程度还要继续加强

具体的分析可以看这里~

poj3468题解

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
int T,n,m,num,a,b,SUM,MAXV;

struct node
{
int L,R;
long long nSum;  //原来的求和
long long Inc;  //区间更新的延迟累加
int mid()
{
return (L+R)/2;
}
} tree[400010];
int nCount = 0;

void build(int root,int L,int R)
{
tree[root].L = L;
tree[root].R = R;
tree[root].nSum = 0;
tree[root].Inc = 0;
if(L==R)
return;
else
{
build(root*2,L,(L+R)/2);
build(root*2+1,(L+R)/2+1,R);
}
}
void insert(int root,int i,int v)
{
if (tree[root].L ==tree[root].R)
{
tree[root].nSum = v;
return ;
}
tree[root].nSum += v;
if (i<=tree[root].mid())
insert(root*2,i,v);
else
insert(root*2+1,i,v);
}

//对a~b范围内的每一个数都加c
void RangeAdd(int root,int a,int b,long long c)
{
if (tree[root].L==a && tree[root].R ==b)
{
tree[root].Inc += c;
return;
}
tree[root].nSum += c*(b-a+1);
if( b <= tree[root].mid())
RangeAdd(root*2,a,b,c);
else if (a >=tree[root].mid()+1 )
RangeAdd(root*2+1,a,b,c);
else
{
RangeAdd(root*2,a,tree[root].mid(),c);
RangeAdd(root*2+1,tree[root].mid()+1,b,c);
}
}

long long querynSum(int root,int a,int b)
{
if (tree[root].L ==a && tree[root].R==b)
{
return tree[root].nSum +
(tree[root].R - tree[root].L + 1) * tree[root].Inc;

}
tree[root].nSum += (tree[root].R - tree[root].L +1)*tree[root].Inc;
RangeAdd(root*2,tree[root].L,tree[root].mid(),tree[root].Inc);
RangeAdd(root*2+1,tree[root].mid()+1,tree[root].R,tree[root].Inc);
tree[root].Inc = 0;
if ( b <= tree[root].mid() )
return querynSum(root*2,a,b);
else if (a > tree[root].mid())
return querynSum(root*2+1,a,b);
else
{
return querynSum(root*2,a,tree[root].mid()) + querynSum(root*2+1,tree[root].mid()+1,b);
}
}

int main()
{
//freopen("in.txt","r",stdin);
int n,q,a,b,c;
char cmd[10];
scanf("%d%d",&n,&q);
int i;
nCount = 0;
build(1,1,n);
for( i = 1; i <= n; i ++ )
{
scanf("%d",&a);
insert(1,i,a);
}
for( i = 0; i < q; i ++ )
{
scanf("%s",cmd);
if ( cmd[0] == 'C' )
{
scanf("%d%d%d",&a,&b,&c);
RangeAdd(1,a,b,c);
}
else
{
scanf("%d%d",&a,&b);
printf("%I64d\n",querynSum(1,a,b));
}
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: