这道题和HDU 1166 敌兵布阵 差不多 都属于线段树的模版题
HDU 1166 敌兵布阵 考的是点更新 这道题考的是段更新 多了一个延时更新的操作 要是没这个操作 每回都更新到底 绝对超时 这就是点更新和段更新的区别了
这个延时操作也不是自己写的 贴的模版 没搞太懂 下来要花点时间弄懂了 应为这个很重要
下面看看代码
#include<cstdio>
#include<cstring>
#define L(u) (u<<1)
#define R(u) (u<<1|1)
#define LL long long
const int maxn = 100005;
LL A[maxn];
struct Node
{
int left,right;
LL add,sum;
} node[maxn<<2];
struct Order
{
char str[5];
int i,j;
}order;
/*核心 延时更新 查询但那里更新到哪里*/
void Pushdown(int u)
{
node[L(u)].add +=node[u].add;
node[L(u)].sum += (node[L(u)].right - node[L(u)].left+1)*node[u].add;
node[R(u)].add += node[u].add;
node[R(u)].sum += (node[R(u)].right - node[R(u)].left+1)*node[u].add;
node[u].add = 0;
}
void Build(int u,int left,int right)
{
node[u].left = left;
node[u].right = right;
node[u].add = 0;
if(node[u].left == node[u].right)
{
node[u].sum = A[left];
return ;
}
int mid = (node[u].left + node[u].right)>>1;
Build(L(u),left,mid);
Build(R(u),mid+1,right);
node[u].sum = node[L(u)].sum + node[R(u)].sum;
}
void Updata(int u,int left,int right,LL val)
{
if(left <= node[u].left && node[u].right <= right )
{
node[u].add +=val;
node[u].sum +=(node[u].right-node[u].left+1)*val;
return ;
}
node[u].sum += (right-left+1)*val;
if(node[u].add)Pushdown(u);
int mid=(node[u].left+node[u].right)>>1;
if(right <= mid ) Updata(L(u),left,right,val);
else
if(left > mid)Updata(R(u),left,right,val);
else
{
Updata(L(u),left,mid,val);
Updata(R(u),mid+1,right,val);
}
}
LL Query(int u,int left,int right)
{
if(left <= node[u].left && node[u].right <= right)
return node[u].sum;
if(node[u].add)Pushdown(u);//延时更新
int mid = (node[u].left + node[u].right)>>1;
if(right <= mid) return Query(L(u),left,right);
else if(left > mid)return Query(R(u),left,right);
else return (Query(L(u),left,mid)+ Query(R(u),mid+1,right));
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
int Q,N;
while(scanf("%d%d",&N,&Q)!=EOF)
{
for(int i = 1; i <= N; i++)
scanf("%lld",&A[i]);
getchar();
Build(1,1,N);
while(Q--)
{
scanf("%s",order.str);
if(order.str[0]=='Q')
{
scanf("%d%d",&order.i,&order.j);
printf("%lld\n",Query(1,order.i,order.j));
}
else
{
LL val;
scanf("%d%d%lld",&order.i,&order.j,&val);
Updata(1,order.i,order.j,val);
}
}
}
return 0;
}