/**
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));
}
}
}
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));
}
}
}