1. 程式人生 > >線段樹專輯(轉)

線段樹專輯(轉)

這幾天陸陸續續更新了下邊幾道我所能找到得具有一些代表性的線段樹題目
從最最簡單的區間求和到對區間的各種操作都包涵在這些題目裡了
相信對一些準備學習線段樹的人有一定得幫助
突然發現自己對資料結構的題目非常有感覺,所以在刷下邊的題的同時也生出靈感出了好幾道線段樹題目
等比賽結束後也會陸續加進裡邊


快半年過去程式碼風格也有很大的改變,感覺以前寫的程式碼很不規範,用自己在預定義中定義的一些函式,但後來感覺作用不是很大,所以又刪去了,所以現在看程式碼可能找不到以前我定義的一些函式,本來想更新一下的,無奈這些函式用的太多,改之太過麻煩,所以在此處申明一下
#define LL(x) ((x)<<1)
#define RR(x) ((x)<<1|1)
#define FF(i,n) for(int i = 0 ; i < n ; i ++)
若還有不清楚的地方,只管提出來便是,我一定一一改正

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
struct Seg_Tree{
	int left,right,num;
	int calmid() {
		return (left+right)/2;
	}
}tt[150000];
int num[50001];
int build(int left,int right,int idx) {
	tt[idx].left = left;
	tt[idx].right = right;
	if(left == right) {
		return tt[idx].num = num[left];
	}
	int mid = (left + right)/2;
	return
tt[idx].num = build(left,mid,LL(idx)) + build(mid+1,right,RR(idx)); }   void update(int id,int x,int idx) { tt[idx].num += x; if(tt[idx].left == tt[idx].right) { return ; } int mid = tt[idx].calmid(); if(id <= mid) { update(id,x,LL(idx)); } else { update(id,x,RR(idx)); } }   int query(int left,int right,int idx) { if(left == tt[idx].left && right == tt[idx].right) { return tt[idx].num; } int mid = tt[idx].calmid(); if(right <= mid) { return query(left,right,LL(idx)); } else if(mid < left) { return query(left,right,RR(idx)); } else { return query(left,mid,LL(idx)) + query(mid+1,right,RR(idx)); } }   int main() { int T; scanf(%d”,T); FF(cas,T) { int n; scanf(%d”,&n); FOR(i,1,1+n) { scanf(%d”,num[i]); } build(1,n,1); printf("Case %d:/n",cas+1); char com[9]; while(scanf("%s",com)) { if(strcmp(com,"End") == 0) break; int a,b; scanf("%d%d",&a,&b); switch(com[0]) { case 'Q': printf("%d/n",query(a,b,1)); break; case 'A': update(a,b,1); break; case 'S': update(a,-b,1); break; } } } return 0; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
struct Seg_Tree {
	int left,right,val;
	int calmid() {
		return (left+right)/2;
	}
}tt[600000];
int val[200001];
 
int build(int left,int right,int idx) {
	tt[idx].left = left;
	tt[idx].right = right;
	if(left == right) {
		return tt[idx].val = val[left];
	}
	int mid = tt[idx].calmid();
	return tt[idx].val = max(build(left,mid,LL(idx)) , build(mid+1,right,RR(idx)));
}
 
void update(int id,int x,int idx) {
	if(tt[idx].left == tt[idx].right){
		tt[idx].val = x;
		return ;
	}
	int mid = tt[idx].calmid();
	if(id <= mid) {
		update(id,x,LL(idx));
	} else {
		update(id,x,RR(idx));
	}
	tt[idx].val = max(tt[LL(idx)].val , tt[RR(idx)].val);
}
 
int query(int left,int right,int idx) {
	if(left == tt[idx].left && right == tt[idx].right) {
		return tt[idx].val;
	}
	int mid = tt[idx].calmid();
	if(right <= mid) {
		return query(left,right,LL(idx));
	} else if(mid < left) {
		return query(left,right,RR(idx));
	} else {
		return max(query(left,mid,LL(idx)) , query(mid+1,right,RR(idx)));
	}
}
 
int main() {
	int n , m ;
	while(scanf("%d%d",&n,&m) == 2) {
		FOR(i,1,n+1) {
			scanf("%d",&val[i]);
		}
		build(1,n,1);
		while(m --) {
			char com[2];
			int a,b;
			scanf("%s%d%d",com,&a,&b);
			if(com[0] == 'Q') {
				printf("%d/n",query(a,b,1));
			} else {
				update(a,b,1);
			}
		}
	}
	return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
int n;
struct Seg_Tree{
	int left,right,col;
}tt[300000];
 
void build(int left,int right,int idx) {
	tt[idx].left = left;
	tt[idx].right = right;
	tt[idx].col = 1;
	if(left == right)	return ;
	int mid = (left + right)/2;
	build(left,mid,LL(idx));
	build(mid+1,right,RR(idx));
}
 
void update(int left,int right,int col,int idx) {
	if(left <= tt[idx].left && right >= tt[idx].right) {
		tt[idx].col = col;
		return ;
	}
	if(tt[idx].col != -1) {
		tt[LL(idx)].col = tt[RR(idx)].col = tt[idx].col;
		tt[idx].col = -1;
	}
	int mid = (tt[idx].left + tt[idx].right)/2;
    if(left <= mid) update(left,right,col,LL(idx));
    if(mid < right)    update(left,right,col,RR(idx));
 
}
 
int query(int left,int right,int idx) {
	if(left == tt[idx].left && right == tt[idx].right) {
		if(tt[idx].col != -1) {
			return (right - left + 1) * tt[idx].col;
		} else {
			int mid = (tt[idx].left + tt[idx].right)/2;
			return query(left,mid,LL(idx)) + query(mid+1,right,RR(idx));
		}
	}
	int mid = (tt[idx].left + tt[idx].right)/2;
	if(right <= mid) {
		return query(left,right,LL(idx));
	} else if(left > mid) {
		return query(left,right,RR(idx));
	} else {
		return query(left,mid,LL(idx)) + query(mid+1,right,RR(idx));
	}
}
 
int main() {
	int T;
	scanf("%d",&T);
	FF(cas,T) {
		int n , m ;
		scanf("%d",&n);
		build(1,n,1);
		scanf("%d",&m);
		while(m --) {
			int left,right,col;
			scanf("%d%d%d",&left,&right,&col);
			update(left,right,col,1);
		}
		printf("Case %d: The total value of the hook is %d./n",cas+1,query(1,n,1));
	}
	return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
struct Seg_Tree {
	int left,right,val;
	int calmid() {
		return (left+right)/2;
	}
}tt[15000];
int val[5001];
 
void build(int left,int right,int idx) {
	tt[idx].left = left;
	tt[idx].right = right;
	tt[idx].val = 0;
	if(left == right) {
		return ;
	}
	int mid = tt[idx].calmid();
	build(left,mid,LL(idx));
	build(mid+1,right,RR(idx));
}
 
int query(int left,int right,int idx) {
	if(left == tt[idx].left && right == tt[idx].right) {
		return tt[idx].val;
	}
	int mid = tt[idx].calmid();
	if(right <= mid) {
		return query(left,right,LL(idx));
	} else if(mid < left) {
		return query(left,right,RR(idx));
	} else {
		return query(left,mid,LL(idx)) + query(mid+1,right,RR(idx));
	}
}
 
void update(int id,int idx) {
	tt[idx].val ++;
	if(tt[idx].left == tt[idx].right) {
		return ;
	}
	int mid = tt[idx].calmid();
	if(id <= mid) {
		update(id,LL(idx));
	} else {
		update(id,RR(idx));
	}
}
 
int main() {
	int n;
	while(scanf("%d",&n) == 1) {
		build(0,n-1,1);
		int sum = 0;
		FF(i,n) {
			scanf(%d”,&val[i]);
			sum += query(val[i],n-1,1);
			update(val[i],1);
		}
		int ret = sum;
		FF(i,n) {
			sum = sum - val[i] + (n - val[i] - 1);
			checkmin(ret,sum);
		}
		printf("%d/n",ret);
	}
	return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
struct Node{
	int idx;
	int val;
	friend bool operator < (Node a,Node b) {
		if(a.val == b.val) {
			return a.idx > b.idx;
		}
		return a.val < b.val;
	}
};
struct Seg_Tree {
	int left,right;
	Node node;
	int add;
	int calmid() {
		return (left+right)/2;
	}
}tt[300000];
 
void build(int left,int right,int idx) {
	tt[idx].left = left;
	tt[idx].right = right;
	tt[idx].add = 0;
	tt[idx].node.idx = left;
	tt[idx].node.val = 0;
	if(left == right) {
		return ;
	}
	int mid = tt[idx].calmid();
	build(left,mid,LL(idx));
	build(mid+1,right,RR(idx));
}
 
void update(int left,int right,int add,int idx) {
	if(left <= tt[idx].left && right >= tt[idx].right) {
		tt[idx].node.val += add;
		tt[idx].add += add;
		return ;
	}
	if(tt[idx].add)