线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和

来源:互联网 发布:预制梁悬臂参数c算法 编辑:程序博客网 时间:2024/05/22 13:32
poj3468 A Simple Problem with Integers
题意:O(-1)
思路:O(-1)

线段树功能:update:成段增减 query:区间求和

Sample Input

10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915

Hint

The sums may exceed the range of 32-bit integers.

题目大意:  

N个数 M个操作 每个操作分Q a b得区间(a,b)的和;C a b c 区间[a,b]里面每个元素的value加c 

由于是成段更新 要用到延迟标记type; 每次C操作 只更新到和某个节点的区间范围一致,下次在访问的时候 延迟标记下移


#include <cstdio>#include <algorithm>using namespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const int maxn = 111111;struct Tree{__int64 value;__int64 type;}tree[maxn<<2];void PushUp(int rt) {tree[rt].value = tree[rt<<1].value + tree[rt<<1|1].value;}void PushDown(int rt,int ms) {if (tree[rt].type) {tree[rt<<1].type += tree[rt].type;tree[rt<<1|1].type += tree[rt].type ;tree[rt<<1].value += (ms - (ms >> 1)) * tree[rt].type;tree[rt<<1|1].value += (ms >> 1) * tree[rt].type;tree[rt].type = 0;}}void build(int l,int r,int rt) {tree[rt].type=0;__int64 val;if (l == r){scanf("%I64d",&val);tree[rt].value=val;return ;}int m = (l + r) >> 1;build(lson);build(rson);PushUp(rt);}void update(int L,int R,int c,int l,int r,int rt) {if (L <= l && r <= R) {//标记1  //更新到这就行,不一定更新到最底端tree[rt].type += c;tree[rt].value += c * (r - l + 1);return ;}PushDown(rt , r - l + 1);//延迟标记,这时候后推, (标记2)//比如建了 [1,4]  然后我们第一次的时候是更新[1,2]// [1,2][3,4]  [1,2]的type就是非0,value往上更新;//   [1][2][3][4]  第二次如果还是要更新[1,2] 在标记1直接更新int m = (l + r) >> 1;   // 而如果你是要更新[1,1](必定访问到标记2) 那么先进行标记2 让两儿子的value更新 if (L <= m) update(L , R , c , lson); //记得这时候儿子type被赋值,自己type=0;if (R > m) update(L , R , c , rson);PushUp(rt);}__int64 query(int L,int R,int l,int r,int rt) {      if (L <= l && r <= R) {          return tree[rt].value;      }  PushDown(rt , r - l + 1); //注意这里    int m = (l + r) >> 1;     //如果之前标记[1,4]type!=0 然后我们现在    __int64 ret = 0;         //如果是访问[1,4]第一步直接得到返回值是没有问题    if (L <= m) ret += query(L , R , lson);  //但访问[1,3]的时候要要把之前的[1,4]延迟标记下移    if (R > m) ret += query(L , R , rson);      return ret;  }  int main() {int N , Q;scanf("%d%d",&N,&Q);build(1 , N , 1);while (Q --) {char op[2];int a , b , c;scanf("%s",op); //防止用%c 会接受回车 新技能get√if (op[0] == 'Q') {scanf("%d%d",&a,&b);printf("%lld\n",query(a , b , 1 , N , 1));} else {scanf("%d%d%d",&a,&b,&c);update(a , b , c , 1 , N , 1);}}return 0;}


0 0
原创粉丝点击