前言:前一段时间在网上找了一个线段树题目列表,我顺着做了一些,今天我把做过的整理一下。感觉自己对线段树了解的还不是很深,自己的算法能力还要加强。光练代码能力还是不够的,要多思考。向队友学习,向大牛学习。

 

ZOJ1610

题目大意:先后对线段涂色,最后统计每种颜色出现的段数,为0则不输出。

分析:以点建树,每个节点有一个标记col,初始为-1,表示未涂过色。涂色时,若完全覆盖,则col为颜色编号,若覆盖一部分,则先将标记下放到左右儿子节点,再将标号标记为-2,表示此节点被部分覆盖过。最后从根节点开始往下遍历,若遇到节点col>-1的,直接将区间l到r标记为true,若col为-1,则返回,若为-2,则分别到左右儿子遍历。

参考代码:

 1 //
 2 //  ZOJ1610.cpp
 3 //  线段树
 4 //
 5 //  Created by TimmyXu on 13-8-11.
 6 //  Copyright (c) 2013年 TimmyXu. All rights reserved.
 7 //
 8 
 9 #include <iostream>
10 #include <cstdio>
11 #include <cstring>
12 #include <string>
13 #include <algorithm>
14 
15 const int maxn = 8000 + 10;
16 
17 struct node
18 {
19     int l,r,col;
20 }tree[maxn<<2];
21 
22 int n,le,ri,c,tmp,mark[maxn],color[maxn];
23 
24 void buildtree(int root,int l,int r)
25 {
26     tree[root].l = l;
27     tree[root].r = r;
28     tree[root].col = -1;
29     if (l < r)
30     {
31         buildtree(root<<1, l, (l+r)/2);
32         buildtree(root<<1|1, (l+r)/2+1, r);
33     }
34 }
35 
36 void update(int root,int l,int r,int c)
37 {
38     if (l <= tree[root].l && tree[root].r <= r)
39     {
40         tree[root].col = c;
41         return;
42     }
43     int mid = (tree[root].l+tree[root].r)/2;
44     if (tree[root].col > -2)
45     {
46         tree[root<<1].col = tree[root<<1|1].col = tree[root].col;
47         tree[root].col = -2;
48     }
49     if (l <= mid) update(root<<1, l, r, c);
50     if (mid < r) update(root<<1|1, l, r, c);
51 }
52 
53 void cnt(int root)
54 {
55     if (tree[root].col > -1)
56     {
57         for (int i = tree[root].l;i <= tree[root].r;i++)
58             mark[i] = tree[root].col;
59         return;
60     }
61     if (tree[root].col == -2)
62     {
63         cnt(root<<1);
64         cnt(root<<1|1);
65     }
66 }
67 
68 int main()
69 {
70     while (scanf("%d",&n)!=EOF)
71     {
72         buildtree(1,0,8000);
73         memset(mark,-1,sizeof(mark));
74         memset(color,0,sizeof(color));
75         while (n--)
76         {
77             scanf("%d%d%d",&le,&ri,&c);
78             update(1,le+1,ri,c);
79         }
80         cnt(1);
81         tmp = -1;
82         for (int i = 0;i <= 8000;i++)
83         {
84             if (tmp == mark[i]) continue;
85             tmp = mark[i];
86             if (tmp != -1) color[tmp]++;
87         }
88         for (int i = 0;i <= 8000;i++)
89             if (color[i])
90                 printf("%d %d\n",i,color[i]);
91         printf("\n");
92     }
93 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-17
  • 2022-12-23
  • 2022-02-13
  • 2021-12-14
相关资源
相似解决方案