poj3468 第二颗线段树。。。

来源:互联网 发布:mt3601 数据手册 编辑:程序博客网 时间:2024/05/21 07:03

/*算了,我还是新手,关键还是在于方向的问题,有时候总是忘记 >= 或者去掉 + 1

关键还是在对于树的构建和存储上还有些不能理解的太清楚,*/



#include <iostream>

#include <cstdio> 


#define LL long long


using namespace std;


struct Node
{
Node *pLeft, *pRight;
int L, R;
LL nSum;
LL lnc;
}; 


Node Tree[200010]; 
int nCount = 0;


int Mid(Node *pRoot)
{
return (pRoot->L + pRoot->R) / 2;
}


void BuildTree(Node *pRoot, int L, int R)
{
pRoot->L = L;
pRoot->R = R;
pRoot->nSum = 0;
pRoot->lnc = 0;
if( L == R ) 
return;

nCount++;
pRoot->pLeft = Tree + nCount;
nCount++;
pRoot->pRight = Tree + nCount;
BuildTree(pRoot->pLeft, L, (L + R) / 2);
BuildTree(pRoot->pRight, (L + R) / 2 + 1, R);
}


void Insert(Node *pRoot, int i, int v)
{
if(pRoot->L == i && pRoot->R == i)
{
pRoot->nSum = v;
return; 
}

pRoot->nSum += v;

if(i <= Mid(pRoot))
Insert(pRoot->pLeft, i, v);
else
Insert(pRoot->pRight, i, v);

}


void Add(Node *pRoot, int a, int b, LL c)
{
if(pRoot->L == a && pRoot->R == b)
{
pRoot->lnc += c;
return;
}

pRoot->nSum += (b - a + 1) * c;

if(b <= (pRoot->L + pRoot->R) / 2)
Add(pRoot->pLeft, a, b, c);
else if (a > (pRoot->L + pRoot->R) / 2)
Add(pRoot->pRight, a, b, c);
else
{
Add(pRoot->pLeft, a, (pRoot->L + pRoot->R) / 2, c);
Add(pRoot->pRight, (pRoot->L + pRoot->R) / 2 + 1, b, c);
}




LL QuerynSum(Node *pRoot, int a, int b)
{
if(pRoot->L == a && pRoot->R == b)
return pRoot->nSum + pRoot->lnc * (pRoot->R - pRoot->L + 1);

pRoot->nSum += (pRoot->R - pRoot->L + 1) * pRoot->lnc;

Add(pRoot->pLeft, pRoot->L, Mid(pRoot), pRoot->lnc);
Add(pRoot->pRight, Mid(pRoot) + 1, pRoot->R, pRoot->lnc);

pRoot->lnc = 0;

if(b <= Mid(pRoot))
return QuerynSum(pRoot->pLeft, a, b);
else if(a > Mid(pRoot))
return QuerynSum(pRoot->pRight, a, b);
else
return QuerynSum(pRoot->pLeft, a, Mid(pRoot)) + QuerynSum(pRoot->pRight, Mid(pRoot) + 1, b);
}


int main()
{
int n, q, i, j, k, a, b, c;
char cmd[10];
scanf ("%d%d", &n, &q);
nCount = 0;
BuildTree(Tree, 1, n);

for (i = 0; i < n; ++i)
{
scanf ("%d", &a );
Insert(Tree, i + 1, a);
}

for(i = 0; i < q; ++i)
{
scanf("%s", cmd);
if(cmd[0] == 'C')
{
scanf ("%d%d%d", &a, &b, &c);
Add(Tree, a, b, c);
}
else
{
scanf("%d%d", &a, &b);
printf("%I64d\n", QuerynSum(Tree, a, b));
}
}

return 0;
}
0 0
原创粉丝点击