Interval Tree Topic

今天训练的内容是线段树。

线段树的基本结构,空间大小,常用操作的复杂度已不必多说。主要针对训练中出线的一些问题做一些小的总结

总得来说,对于线段树的编码和调试能力还比较欠缺,这一点希望通过多次的训练来解决

对于各种线段树模型,应用方法则需要经验的积累

 

ZJU 1610:

    线段树的入门题,主要注意的是线段树处理过程中一般如果能覆盖当前区间,操作一般都会终止。这种情况下,如果题意中该区间的操作会影响子区间,那么需要通过一些步骤调整。典型的就是染色。对一个染成同一中颜色的区间的一个子区间染色,我们首先先要将该区间的颜色传递到它的子区间上。见代码line39

  1. #include <iostream>
  2. using namespace std;
  3. const int N = 8010;
  4. struct node
  5. {
  6.     int x, y;
  7.     int color;
  8. }seg[3*N];
  9. int cnt[N];
  10. int num[N];
  11. void build(int root, int x, int y)
  12. {
  13.     seg[root] = (node){x, y, -1};
  14.     if(y > x + 1)
  15.     {
  16.         int mid = (x + y) >> 1;
  17.         build(root * 2, x, mid);
  18.         build(root * 2 + 1, mid, y);
  19.     }
  20. }
  21. void insert(int root, int x, int y, int c)
  22. {
  23.     if(x <= seg[root].x && y >= seg[root].y)
  24.     {
  25.         int j = seg[root].color;
  26.         seg[root].color = c;
  27.     }
  28.     else
  29.     {
  30.         int mid = (seg[root].x + seg[root].y) >> 1;
  31.         if(seg[root].color >= 0)
  32.         {
  33.             seg[root*2].color = seg[root*2 + 1].color = seg[root].color;
  34.             seg[root].color = -1;
  35.         }
  36.         if(x < mid) insert(root * 2, x, y, c);
  37.         if(y > mid) insert(root * 2 + 1, x, y, c);
  38.     }
  39. }
  40. void query(int x)
  41. {
  42.     int i, j;
  43.     
  44.     if(seg[x].color >= 0)
  45.         for(int i = seg[x].x + 1; i <= seg[x].y; i++) cnt[i] = seg[x].color;
  46.     else if(seg[x].x + 1 == seg[x].y) cnt[seg[x].y] = -1;
  47.     else
  48.     {
  49.         query(2*x);
  50.         query(2*x+1);
  51.     }
  52. }
  53.         
  54.         
  55. int main()
  56. {
  57.     int i, j, k, m;
  58.     
  59.     while(scanf("%d",&m) == 1)
  60.     {
  61.         memset(cnt, 0, sizeof(cnt));  
  62.         memset(num, 0, sizeof(num));
  63.               
  64.         build(1, 0, 8000);
  65.         for(; m; m--)
  66.         {
  67.             scanf("%d%d%d",&i, &j, &k);
  68.             insert(1, i, j, k);
  69.         }
  70.         query(1);
  71.         
  72.         i = 1;
  73.         while(i <= 8000)
  74.         {
  75.             while(i <= 8000 && cnt[i]==-1) i++;
  76.             if(i > 8000) break;
  77.             j = i + 1;
  78.             while(j <= 8000 && cnt[j]==cnt[i]) j++;
  79.             num[cnt[i]]++;
  80.             i = j;
  81.         }
  82.         for(i = 0; i <= 8000; i++)
  83.             if(num[i] != 0) printf("%d %d/n",i, num[i]);
  84.         
  85.         printf("/n");
  86.     }
  87.     return 0;
  88. }
  89.             
  90.         
  91.     
  92.     

PKU 2777:

      和上题相似。注意的地方在于。查询的时候,递归结束既可能是因为覆盖了整个区间,也可能是整个区间只有一中颜色。

line 54

  1. #include <iostream>
  2. const int N = 100010;
  3. struct node
  4. {
  5.     int x, y;
  6.     int color;
  7.     bool oneColor;
  8. }seg[N<<2];
  9. int T;
  10. void build(int root, int x, int y)
  11. {
  12.     seg[root] = (node){x, y, 1, true};
  13.     if(x != y)
  14.     {
  15.         int mid = (x + y) >> 1;
  16.         build(root * 2, x, mid);
  17.         build(root * 2 + 1, mid + 1, y);
  18.     }
  19. }
  20. void insert(int root, int x, int y, int c)
  21. {
  22.     if(x <= seg[root].x && y >= seg[root].y){
  23.         seg[root].color = (1<<c);
  24.         seg[root].oneColor = true;
  25.     }
  26.     else
  27.     {
  28.         if(seg[root].oneColor) {
  29.             seg[root*2].color = seg[root*2+1].color = seg[root].color;
  30.             seg[root*2].oneColor = seg[root*2+1].oneColor = true;
  31.             if((1<<c) != seg[root].color) seg[root].oneColor = false;
  32.         }
  33.         
  34.         int mid = (seg[root].x + seg[root].y) >> 1;
  35.         if(x <= mid)
  36.             insert(root*2, x, y, c);
  37.         if(y > mid)
  38.             insert(root*2 + 1, x, y, c);
  39.         
  40.         seg[root].color = seg[root*2].color | seg[root*2+1].color;
  41.     }
  42. }
  43. int query(int root, int x, int y)
  44. {
  45.     if(x <= seg[root].x && y >= seg[root].y)
  46.         return seg[root].color;
  47.     
  48.     if(seg[root].oneColor) return seg[root].color;
  49.     
  50.     else
  51.     {
  52.         int mid = (seg[root].x + seg[root].y) >> 1;
  53.         
  54.         int ans = 0;
  55.         if(x <= mid) ans |= query(root*2, x, y);
  56.         if(y > mid)  ans |= query(root*2 + 1, x, y);
  57.         
  58.         return ans;
  59.     }
  60. }
  61. inline int getNum(int x)
  62. {
  63.     int i = 0;
  64.     while(x != 0) { i += x%2; x/=2;}
  65.     return i;
  66. }
  67. int main()
  68. {
  69.     int n, m;
  70.     int i, j, k;
  71.     
  72.     scanf("%d%d%d",&n, &T, &m);
  73.     build(1, 1, n);
  74.     
  75.     for(; m; m--)
  76.     {
  77.         getchar();
  78.         char ch = getchar();
  79.         if(ch == 'C')
  80.         { 
  81.             scanf("%d%d%d",&i, &j, &k);
  82.             if(i > j) { int t = i; i = j; j = t;}
  83.             insert(1, i, j, k-1);
  84.         }
  85.         else
  86.         {
  87.             scanf("%d%d",&i, &j);
  88.             if(i > j) { int t = i; i = j; j = t;}
  89.             printf("%d/n",getNum(query(1, i, j)));
  90.         }
  91.     }
  92.     return 0;
  93. }
  94.     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sure! Here's an example of an interval tree implemented in C: ```c #include <stdio.h> #include <stdlib.h> // Structure to represent an interval struct Interval { int low, high; }; // Structure to represent a node in the interval tree struct Node { struct Interval *interval; int max; struct Node *left, *right; }; // Function to create a new interval tree node struct Node* newNode(struct Interval i) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->interval = (struct Interval*)malloc(sizeof(struct Interval)); node->interval->low = i.low; node->interval->high = i.high; node->max = i.high; node->left = NULL; node->right = NULL; return node; } // Function to insert a new interval into the interval tree struct Node* insert(struct Node* root, struct Interval i) { if (root == NULL) return newNode(i); int l = root->interval->low; if (i.low < l) root->left = insert(root->left, i); else root->right = insert(root->right, i); if (root->max < i.high) root->max = i.high; return root; } // Function to check if two intervals overlap int doOverlap(struct Interval i1, struct Interval i2) { return (i1.low <= i2.high && i2.low <= i1.high); } // Function to search for overlapping intervals in the interval tree void search(struct Node* root, struct Interval i) { if (root == NULL) return; if (doOverlap(*(root->interval), i)) printf("Overlaps with [%d, %d]\n", root->interval->low, root->interval->high); if (root->left != NULL && root->left->max >= i.low) search(root->left, i); search(root->right, i); } // Example usage int main() { struct Interval intervals[] = {{15, 20}, {10, 30}, {17, 19}, {5, 20}, {12, 15}, {30, 40}}; int n = sizeof(intervals) / sizeof(intervals[0]); struct Node* root = NULL; for (int i = 0; i < n; i++) root = insert(root, intervals[i]); struct Interval x = {14, 16}; search(root, x); return 0; } ``` This code implements an interval tree data structure in C. It includes functions to create a new interval tree node, insert an interval into the tree, check if two intervals overlap, and search for overlapping intervals in the tree. The main function provides an example usage of the interval tree.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值