poj 3468解题报告

/**
poj 3468 TL
开始WA 是因为在懒惰标记下移的时候有问题要注意下
改了几次还是超时不知道是不是要数组模拟才行 - -!
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

using namespace std;

#define MAX 100000

typedef struct node
{
int nleft, nright;
struct node* plchild;
struct node* prchild;
long long nValue;
long long nlazy; //
node()
{
nleft = 0 ;
nright = 0;
plchild = NULL;
prchild = NULL;
nValue = 0;
nlazy = 0;
}

}node_t;

static int Arr[MAX];
node_t* m_pRoot = NULL; //

void DownLazy(node_t* pNode);

//建树
node_t* CreateTree(int nleft, int nright)
{
if(nleft > nright) return NULL;

node_t* pNode = new node_t;
pNode->nleft = nleft;
pNode->nright = nright;

if(nleft == nright)
{
pNode->nValue = Arr[nleft];
return pNode;
}

int mid = (nleft + nright) >> 1;
pNode->plchild = CreateTree(nleft, mid);
pNode->prchild = CreateTree(mid + 1, nright);
pNode->nValue = pNode->plchild->nValue + pNode->prchild->nValue;
return pNode;
}


//区间更新
void UpdateTree(node_t* pNode, int nValue, int nleft, int nright)
{
if(pNode->nleft == nleft && pNode->nright == nright)
{
pNode->nValue +=nValue * (nright - nleft + 1);
pNode->nlazy += nValue;
return ;
}

//用标记更新子节点
if(pNode->nlazy != 0)
DownLazy(pNode);

int mid = (pNode->nleft + pNode->nright) >> 1;

if(nright <= mid)
UpdateTree( pNode->plchild,nValue, nleft, nright);
else if(nleft > mid)
UpdateTree( pNode->prchild, nValue, nleft, nright);
else
{
UpdateTree( pNode->plchild,nValue, nleft, mid);
UpdateTree( pNode->prchild,nValue, mid + 1, nright);
}

pNode->nValue = pNode->plchild->nValue + pNode->prchild->nValue;
return ;
}

//下移懒惰标记
void DownLazy(node_t* pNode)
{
int mid = (pNode->nleft + pNode->nright) >> 1;
UpdateTree(pNode->plchild,pNode->nlazy, pNode->nleft, mid);
UpdateTree(pNode->prchild,pNode->nlazy, mid + 1, pNode->nright);
pNode->nlazy = 0;
}

//区间查询
long long QuerySum(node_t* pNode, int nleft, int nright)
{
long long sum = 0;
if(pNode->nleft == nleft && pNode->nright == nright)
{
sum = pNode->nValue;
return sum;
}

//用标记更新子节点
if(pNode->nlazy != 0)
DownLazy(pNode);

int mid = (pNode->nleft + pNode->nright) >> 1;
if(nright <= mid)
sum = QuerySum(pNode->plchild, nleft, nright);
else if(nleft > mid)
sum = QuerySum(pNode->prchild, nleft, nright);
else
sum = QuerySum(pNode->plchild, nleft, mid)\
+ QuerySum(pNode->prchild, mid + 1, nright);

return sum;
}

int main()
{
int N,Q;
memset(Arr, 0, sizeof(Arr));
scanf("%d%d", &N, &Q);
for(int i = 0; i < N; i++)
scanf("%d",Arr + i);

m_pRoot = CreateTree(0, N - 1);

char ch;
int a,b,c;
for(int i=1;i<=Q;i++)
{
cin>>ch;
if(ch == 'C')
{
scanf("%d%d%d",&a,&b,&c);
UpdateTree(m_pRoot, c, a - 1, b - 1);
}
else
{
scanf("%d%d",&a,&b);
printf("%I64d\n",QuerySum(m_pRoot,a - 1,b - 1));
}
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值