程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> PKU3468(A Simple Problem with Integers)線段樹的成段更新

PKU3468(A Simple Problem with Integers)線段樹的成段更新

編輯:C++入門知識

[cpp]  /***********************************************  題目大意:  Q a b   :查詢區間[a,b]的和;  C a b x : 更新區間[a,b],區間所有值加上x;    算法思想:  線段樹的成段更新--延遲更新;  在區間查詢和更新的時候加入一個延遲節點;  每次要在下次查詢或者更新到該區間時;  再把節點的信息傳遞到左右孩子的結點上;  這樣更新大大減少了時間和空間上的開銷;    算法過程:  每次更新並不需要更新到葉節點;  只需更新到相應的段就可以了,然後記錄個add;  下次更新或者查詢的時候,如果要查到該段的子節點;  就把add加到子節點上去,再將該add設為0;  這樣查詢子區間的復雜度就是更新的復雜度;  ************************************************/   #include<iostream>   #include<cstring>   #include<cstdlib>   #include<cstdio>   #include<climits>   #include<algorithm>   using namespace std;      #define L l , m , u << 1   #define R m + 1 , r , u << 1 | 1      typedef long long LL;   const int N = 111111;   LL add[N<<2];   LL sum[N<<2];      void PushUp(int u)//把當前結點的信息更新到父結點   {       sum[u] = sum[u<<1] + sum[u<<1|1];   }      void PushDown(int u,int m)//把當前結點的信息更新給兒子結點   {       if (add[u])       {           add[u<<1] += add[u];           add[u<<1|1] += add[u];           sum[u<<1] += add[u] * (m - (m >> 1));           sum[u<<1|1] += add[u] * (m >> 1);           add[u] = 0;       }   }      void build(int l,int r,int u)   {       add[u] = 0;       if (l == r)       {           scanf("%lld",&sum[u]);           return ;       }       int m = (l + r) >> 1;       build(L);       build(R);       PushUp(u);   }      void update(int l1,int r1,int c,int l,int r,int u)   {       if (l1 <= l && r <= r1)       {           add[u] += c;           sum[u] += (LL)c * (r - l + 1);           return ;       }       PushDown(u , r - l + 1);       int m = (l + r) >> 1;       if (l1 <= m)           update(l1 , r1 , c , L);       if (m < r1)           update(l1 , r1 , c , R);       PushUp(u);   }      LL query(int l1,int r1,int l,int r,int u)   {       if (l1 <= l && r <= r1)       {           return sum[u];       }       PushDown(u , r - l + 1);       int m = (l + r) >> 1;       LL res = 0;       if (l1<= m)           res += query(l1 , r1 , L);       if (m < r1)           res += query(l1 , r1 , R);       return res;   }      int main()   {       //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin);       int N , Q;       scanf("%d%d",&N,&Q);       build(1 , N , 1);       while (Q--)       {           char op[2];           int a , b , c;           scanf("%s",op);           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;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved