线段树区间更新(1)(区间同时加上x)模板(序号从0开始)O(logn)(poj3468)

来源:互联网 发布:mac 能玩魔兽争霸 编辑:程序博客网 时间:2024/05/30 12:31

线段树区间更新模板

AC code

#include <iostream>#include <string>#include<cstring>#include <stdio.h>#include <cmath>#include <algorithm>#include <vector>const int maxn = 1 << 17;const int MOD = 1e9 + 7;const int INF = 0x3f3f3f3f;using namespace std;typedef long long LL;LL data[2*maxn-1],datb[2*maxn-1];int n,q;void init(int n_){    n = 1;    while(n < n_)  n *= 2;}void add(int i,int j,int x,int k,int l,int r){    if(j <= l || i >= r)  return;    if(i<=l&&j>=r) data[k] += x;    else    {        datb[k] += (min(j,r) - max(i,l)) * x;        add(i,j,x,k*2+1,l,(l+r)/2);        add(i,j,x,k*2+2,(l+r)/2,r);            }}LL Query(int i,int j,int k,int l,int r){       if(i >= r || j <= l)   return 0;       if(i <= l && j >= r)   return data[k]*(r-l) + datb[k];       else       {           LL res = data[k] * (min(j,r) - max(i,l));           res += Query(i,j,2*k+1,l,(l+r)/2);           res += Query(i,j,2*k+2,(l+r)/2,r);           return res;          }}int main(){   cin >> n >> q;   int n0 = n;   init(n);   memset(data,0,sizeof(data));   memset(datb,0,sizeof(datb));   for(int i = 0; i < n0; i++)   {       int e;       scanf("%d",&e);       add(i,i+1,e,0,0,n);   }   while(q--)   {       int i,j,x;       char c;       scanf("%*c%c",&c);      if(c=='Q')      {        scanf("%d%d",&i,&j);        printf("%I64d\n",Query(i-1,j,0,0,n));      }       else {           scanf("%d%d%d",&i,&j,&x);               add(i-1,j,x,0,0,n);           }  }   return 0;}
阅读全文
0 0
原创粉丝点击