poj 3468 線段樹 區間和,有更新

2021-06-22 21:09:32 字數 1543 閱讀 3730

題意:給定q(1 ≤ q≤ 100,000)個數a1,a2… aq,,以及可能多次進行的兩個操作:1)對某個區間ai … aj的每個數都加n(n可變)2) 求某個區間ai … aj間所有數的和

思路:線段樹。注意每次更新不更新到葉節點,只更新到完整的區間為止。具體為:增加時如果改變的區間正好覆蓋乙個節點,則增加其節點的flag值,停止更新;否則更新sum值,再將增量往下傳。在查詢時,如果待查區間不是正好覆蓋乙個節點,就將節點的flag往下帶,然後將flag代表的所有增量累加到sum上後將flag清0,接下來再往下查詢。flag往下帶的過程也是區間分解的過程,複雜度是o(log(n))。

#include #include #define n 100005

typedef struct nodetree;

tree t[n*2+1];

tree *root,*alloc;

int n,q;

int getmid(tree *r)

void create(tree *r,int l,int r)

}void insert(tree *r,int i,int x)

void update(tree *r,int l,int r,__int64 c)

r->sum += (r-l+1)*c;

if(r <= mid)

update(r->leftson,l,r,c);

else if(l > mid)

update(r->rightson,l,r,c);

else

}__int64 query(tree *r,int l,int r)

int main()

for(i = 1;i<=q;i++)else

} }return 0;

}

數組建線段樹方法:

#include #include #include #include #define n 100005

#define inf 0x3fffffff

using namespace std;

struct treet[n<<2];

int n,q;

int mid(int a,int b)

void createtree(int root,int a,int b)

}void insert(int root,int id,long long x)

void add(int root,int a,int b,long long x)

t[root].sum += (b-a+1)*x;

if(b <= mm)

add(root*2,a,b,x);

else if (a>mm)

add(root*2+1, a, b, x);

else

}long long query(int root,int a,int b)

}int main()

for(i = 1;i<=q;i++)else

}return 0;

}

POJ 3468 線段樹區間

這個題目是第二個區間修改的線段樹了,做到現在可以發現線段樹真的非常的靈活,特別是區間修改部分,前面的單點修改其實還是也可參看模版的,區間修改就真的非常靈活了了。這個題目就是區間加法,然後求乙個累加和,同樣地也是需要乙個延遲標誌的,也就是lazy,然後還需要乙個統計當前區間的全部和的陣列。就可以輕鬆解...

POJ 3468《線段樹,區間add

題目連線 位運算 k 1 相當於 k 2 k 1 1 相當於 k 2 1 修改區間內的值,並且維護區間和。詳見 include include include using namespace std typedef long long ll const int maxn 100000 10 int ...

poj3468線段樹區間修改

題目哈。最近在隊裡的寒假作業中第一次遇到了線段樹的題,之前也聽思雨姐姐說過也看過她寫過,但自己始終沒個影響,然後自己做了幾天也算剛入這個門,會寫一些比較基礎的線段樹了,之所以把這道題寫下來是因為線段樹的精華還是在於區間修改,也是最實用的部分。線段樹的區間修改,最巧妙的部分是建立乙個lazy樹,與各個...