您的位置:首页 > 其它

C - A Simple Problem with Integers - poj 3468(区间更新)

2015-07-26 14:44 288 查看
题意:有一个比较长的区间可能是100000.长度, 每个点都有一个值(值还比较大),现在有一些操作,C abc, 把区间a-b内全部加上c, Qab,求区间ab的值。
分析:很明显我们不可能对区间的每个点都进行更新,不过我们可以使用一个op的开关,如果op等于0说明这个不需要更新,如果等于1就说明需要进行更新,这样只需要和插入的时候进行一下更新即可***********************************************************************注意:在向下更新的时候如果是更新子树有可能一个区间会更新多次,而子树区间更新的时候不能乘本区间的更新值,只能乘根节点的更新值,根节点的跟新值用完后归0; #include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define maxn 100005
#define Lson root<<1,L,tree[root].Mid()
#define Rson root<<1|1,tree[root].Mid()+1,R

struct Tree//op等于0的时候子树不需要更新,op等于1需要更新
{
int L, R, op;//需要向下更新的值为e
long long sum, e;//因为区间和比较大,所以使用long long 保存
int Mid(){return (L+R)/2;}
int Len(){return (R-L+1);}
}tree[maxn*4];
long long val[maxn];

void Down(int root)//向下更新
{
if(tree[root].op && tree[root].L != tree[root].R)
{
tree[root].op = false;
tree[root<<1].op = tree[root<<1|1].op = true;
tree[root<<1].e += tree[root].e;
tree[root<<1|1].e += tree[root].e;

tree[root<<1].sum += tree[root<<1].Len() * tree[root].e;
tree[root<<1|1].sum += tree[root<<1|1].Len() * tree[root].e;

tree[root].e = 0;
}
}
void Build(int root, int L, int R)
{
tree[root].L = L, tree[root].R = R;
tree[root].op = false;

if(L == R)
{
tree[root].sum = val[L];
return ;
}

Build(Lson);
Build(Rson);

tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
}
void Insert(int root, int L, int R, long long e)
{
Down(root);

tree[root].sum += (R-L+1) * e;

if(tree[root].L == L && tree[root].R == R)
{
tree[root].e = e, tree[root].op = true;
return ;
}

if(R <= tree[root].Mid())
Insert(root<<1, L, R, e);
else if(L > tree[root].Mid())
Insert(root<<1|1, L, R, e);
else
{
Insert(Lson, e);
Insert(Rson, e);
}
}
long long Query(int root, int L, int R)
{
Down(root);

if(tree[root].L == L && tree[root].R == R)
return tree[root].sum;
if(R <= tree[root].Mid())
return Query(root<<1, L, R);
else if(L > tree[root].Mid())
return Query(root<<1|1, L, R);
else
return Query(Lson) + Query(Rson);
}

int main()
{
int i, N, Q;

while(scanf("%d%d", &N, &Q) != EOF)
{
for(i=1; i<=N; i++)
scanf("%I64d", &val[i]);
Build(1, 1, N);

int a, b; char s[10];
long long c;

while(Q--)
{
scanf("%s%d%d", s, &a, &b);

if(s[0] == 'C')
{
scanf("%I64d", &c);
Insert(1, a, b, c);
}
else
{
long long ans = Query(1, a, b);
printf("%I64d\n", ans);
}
}
}

return 0;
}

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