# 线段树基础题目

## poj2777 Count Color（染色性线段树）

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <string>
#include <cmath>
#include <iomanip>
#include <limits>
#include <algorithm>
#include <ctime>
using namespace std;
const int MAXN = 1e5+5;
int vis[35] = { 0 };
int lazy[MAXN * 4] = { 0 };
int tree[MAXN * 4];
int L, T, O,ans;
void init() {
for (int i = 0;i < MAXN * 4;i++) {
tree[i] = 1;
}
memset(lazy, 0, sizeof lazy);
memset(vis, 0, sizeof vis);
}
void push_down(int rt) {
lazy[rt * 2] = lazy[rt];
lazy[rt * 2 + 1] = lazy[rt];
tree[rt * 2] = lazy[rt];
tree[rt * 2 + 1] = lazy[rt];
lazy[rt] = 0;
}
void update(int l, int r, int tar, int left, int right, int rt) {
if (l <= left && r >= right) {
lazy[rt] = tar;
tree[rt] = tar;
return;
}
if (lazy[rt]) {
push_down(rt);
}
int mid = (left + right) / 2;
if (l <= mid)update(l, r, tar, left, mid, 2 * rt);
if (r > mid)update(l, r, tar, mid + 1, right, 2 * rt + 1);
if (tree[2 * rt] == tree[2 * rt + 1]) {
tree[rt] = tree[rt * 2];
}
else {
tree[rt] = -1;
}
}
void query(int l, int r, int left, int right, int rt) {
if (l <= left && r >= right) {
if (tree[rt] == 0)return;//这题要不要无所谓
if (tree[rt] == -1) {
if (lazy[rt])push_down(rt);//要不要无所谓，因为tree和lazy改变有2个方式，一个是update，那么这2个一起改，一个是pushdown，但是也是一起改的。所以tree为-1时，lazy必定是0.
int mid = (left + right) / 2;
if (l <= mid)query(l, r, left, mid, 2 * rt);
if (r > mid)query(l, r, mid + 1, right, 2 * rt + 1);

}
else {
if (vis[tree[rt]] == 0) {
ans++;
vis[tree[rt]] = 1;
}
}
return;
}
if (lazy[rt])push_down(rt);
int mid = (left + right) / 2;
if (mid >= l)query(l, r, left, mid, 2 * rt);
if (r > mid)query(l, r, mid + 1, right, 2 * rt + 1);
}
int main() {
std::ios::sync_with_stdio(false);
while (cin>>L>>T>>O) {
init();
while (O--) {
char c;
cin >> c;
if (c == 'C') {
int a, b, c;
cin >> a >> b >> c;
if (b < a) {
int tmp = b;
b = a;
a = tmp;
}
update(a, b, c, 1, L, 1);
}
if (c == 'P') {
memset(vis, 0, sizeof vis);
ans = 0;
int a, b;
cin >> a >> b;
if (b < a) {
int tmp = b;
b = a;
a = tmp;
}
query(a, b, 1, L, 1);
cout << ans << endl;
}
}

}
}


## poj3264 Balanced Lineup（区间查询，维护双值）

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <string>
#include <cmath>
#include <iomanip>
#include <limits>
#include <algorithm>
#include <ctime>
using namespace std;
const int MAXN = 2e5+5;
struct Tree {
int maxn, minn, l, r;
}tree[MAXN*4];
int num[MAXN];
int N, Q;
void buildtree(int left, int right, int rt) {
tree[rt].l = left;
tree[rt].r = right;
if (left == right) {
tree[rt].maxn = num[left];
tree[rt].minn = num[left];
return;
}
int mid = (left + right) / 2;
buildtree(left, mid, rt * 2);
buildtree(mid + 1, right, 2 * rt + 1);
tree[rt].maxn = max(tree[rt *2].maxn, tree[rt * 2 + 1].maxn);
tree[rt].minn = min(tree[rt * 2].minn, tree[rt * 2 + 1].minn);
}
int maxx = 0, minx = 1e9;
void query(int l, int r, int left, int right, int rt) {
if (l <= left && r >= right) {
maxx = max(maxx, tree[rt].maxn);
minx = min(minx, tree[rt].minn);
return;
}
int mid = (left + right) / 2;
if (l <= mid)query(l, r, left, mid, 2 * rt);
if (r > mid)query(l, r, mid + 1, right, 2 * rt + 1);
}
int main() {
std::ios::sync_with_stdio(false);
cin >> N >> Q;
for (int i = 1;i <= N;i++) {
cin >> num[i];
}
buildtree(1, N, 1);
for (int i = 1;i <= Q;i++) {
maxx =0 , minx = 1e9;
int a, b;
cin >>  a >> b;
query(a, b, 1, N, 1);
//cout << maxx << " "<<minx << endl;
cout << maxx - minx << endl;
}
}


## poj3468 A simple Problem with integers（区间修改）

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <string>
#include <cmath>
#include <iomanip>
#include <limits>
#include <algorithm>
#include <ctime>
using namespace std;
const int MAXN = 1e5+5;
long long tree[MAXN * 4];
long long lazy[MAXN * 4] = { 0 };
int N, Q;
long long num[MAXN];
void buildtree(int left, int right, int rt) {
if (left == right) {
tree[rt] = num[left];
return;
}
int mid = (left + right) / 2;
buildtree(left, mid, rt * 2);
buildtree(mid + 1, right, rt * 2 + 1);
tree[rt] = tree[rt * 2] + tree[rt * 2 + 1];
}
void push_down(long long len,int rt) {
tree[rt * 2] += lazy[rt] * (len - len / 2);
tree[rt * 2 + 1] += lazy[rt] * (len / 2);
lazy[2 * rt] += lazy[rt];
lazy[2 * rt + 1] += lazy[rt];
lazy[rt] = 0;
}
void update(int l, int r, int tar, int left, int right, int rt) {
if (l <= left && r >= right) {
lazy[rt] += tar;
tree[rt] += (right-left+1)*tar;
return;
}
if (lazy[rt])push_down(right-left+1,rt);
int mid = (left + right) / 2;
if(l<=mid)update(l, r, tar, left, mid, rt * 2);
if(r>mid)update(l, r, tar, mid + 1, right, rt * 2 + 1);
tree[rt] = tree[rt * 2] + tree[rt * 2 + 1];
}
long long query(int l, int r, int left, int right, int rt) {
if (l <= left && r >= right)return tree[rt];
if (lazy[rt])push_down(right - left + 1, rt);
int mid = (left + right) / 2;
long long ans = 0;
if (l <= mid)ans += query(l, r, left, mid, 2 * rt);
if (r > mid)ans += query(l, r, mid + 1, right, 2 * rt + 1);
return ans;
}
int main() {
std::ios::sync_with_stdio(false);
cin >> N >> Q;
for (int i = 1;i <= N;i++) {
cin >> num[i];
}
buildtree(1, N, 1);
while (Q--) {
char a;
cin >> a;
if (a == 'Q') {
int b, c;
cin >> b >> c;
cout << query(b, c, 1, N, 1)<<endl;
}
if (a == 'C') {
int b, c, d;
cin >> b >> c >> d;
update(b, c, d, 1, N, 1);
}
}
return 0;
}

08-09 8731
04-20 572

08-06 4万+
08-06 704
03-11 817
08-22 3万+
12-20 435