題意:給定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樹,與各個...