您的位置:首页 > 其它

poj -- 3468

2015-06-10 20:24 330 查看
很明显 用线段树

节点类型 :

typedef struct _NODE_
{
int L,R;
_NODE_* pLeft;
_NODE_* pRight;
LL nSum; // 原来的和
LL lnc; //增加量c的累加
}NODE;

感觉用孩子节点比较好一点 开到2n就行了

用2*n+1/2*n+2的话 要开到4n

http://poj.org/problem?id=3468

#include<iostream>
#include<cstdio>
using namespace std;

const int maxn = 200000 + 10;
typedef long long LL;
typedef struct _NODE_
{
int L,R;
_NODE_* pLeft;
_NODE_* pRight;
LL nSum;
LL lnc;
}NODE;

NODE Tree[maxn];
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+=c*(b-a+1);
if (b<=(pRoot->L+pRoot->R)/2)
{
Add(pRoot->pLeft,a,b,c);
}
else if (a>=(pRoot->L+pRoot->R)/2+1)
{
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->R-pRoot->L+1)*pRoot->lnc;
}

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)+1)
{
return QuerynSum(pRoot->pRight,a,b);
}
else
{
return QuerynSum(pRoot->pLeft,a,Mid(pRoot))+QuerynSum(pRoot->pRight,Mid(pRoot)+1,b);
}

}

void work()
{
int i,j,k;
int n,q;
scanf("%d%d",&n,&q);
int a,b,c;
nCount = 0;
char cmd[10];
BuildTree(Tree,1,n);
for (i = 1;i<=n;i++)
{
scanf("%d",&a);
Insert(Tree,i,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 ;
}
int main()
{
work();
return 0;
}


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