zoj 1610 线段树

思路:线段树的入门题目,先染色,最后统计,color=-2表示区间有多种颜色,-1表示未涂颜色

 

 

 

 

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <string>
  5. #include <cctype>
  6. #include <queue>
  7. /*
  8. #include <list>
  9. #include <stack>
  10. #include <set>
  11. #include <map>
  12. #include <cmath>
  13. */
  14. using namespace std;
  15. #define ma(a,b) (a)>(b)?(a):(b)
  16. #define mi(a,b) (a)<(b)?(a):(b)
  17. #define FF(i,a,b) for(int i=(a);i<=(b);i++)
  18. #define RR(i,b) for(int i=(0);i<(b);i++)
  19. #define clr(x) memset(x,0,sizeof(x))
  20. #define pb push_back
  21. #define mp make_pair
  22. #define sz size()
  23. #define F  first
  24. #define S  second
  25. #define vv vector
  26. #define ii iterator
  27. /*
  28. #include <sstream>
  29. #include <iterator>
  30. #define ssm stringstream
  31. */
  32. #define cn continue
  33. #define br break
  34. typedef int type;
  35. const int ST = 0;
  36. #define out(x) cout << #x << "=" << x << endl
  37. template <class T> void show(T a, int n) { for (int i = ST; i < ST+n; i++) { cout<<a[i]<<' '; } cout<<endl; }
  38. template <class T> void show(T a, int r, int l) { for (int i = ST; i < ST+r; i++) show(a[i], l); cout<<endl; }
  39. const int N = 10000, M = 8000;
  40. struct node
  41. {
  42.  int l,r,color;
  43. };
  44. node a[3*M];
  45. int n, b[N], num[N];
  46. void build(int root, int x, int y)
  47. {
  48.  int len=y-x;
  49.  a[root] = (node){x,y,-1};
  50.  if(len>1)
  51.  {
  52.   int mid=(x+y)/2;
  53.   build(root*2,x,mid);
  54.   build(root*2+1,mid,y);
  55.  }
  56. }
  57. void insert(int root, int x1, int x2, int c)
  58. {
  59.  int mid=(a[root].l+a[root].r)/2;
  60.  if(a[root].color==c)return;
  61.  if(x1<=a[root].l && x2>=a[root].r)
  62.  {
  63.   a[root].color=c;
  64.  }
  65.  else
  66.  {
  67.   //hint: don't forget
  68.   if(a[root].color>=0)
  69.   {
  70.    a[root*2].color=a[root].color;
  71.    a[root*2+1].color=a[root].color;
  72.   }
  73.   a[root].color=-2;
  74.   if(x1<mid)insert(root*2,x1,x2,c);
  75.   if(x2>mid)insert(root*2+1,x1,x2,c);
  76.  }
  77. }
  78. void paint(int root)
  79. {
  80.  if(a[root].color>=-1)
  81.  {
  82.   for(int i=a[root].l;i<a[root].r;i++)
  83.   {
  84.    b[i]=a[root].color;
  85.   }
  86.  }
  87.  else
  88.  {
  89.   paint(root*2);
  90.   paint(root*2+1);
  91.  }
  92. }
  93. void cal()
  94. {
  95.  paint(1);
  96.  for(int i=0;i<M;i++)
  97.  if(b[i]>=0)
  98.  {
  99.   num[b[i]]++;
  100.   while(i+1<M && b[i]==b[i+1])i++;
  101.  }
  102.  //show(b,10);
  103. }
  104. void print()
  105. {
  106.  for(int i=0;i<=M;i++)
  107.  {
  108.   if(num[i]!=0)
  109.   {
  110.    printf("%d %d/n", i, num[i]);
  111.   }
  112.  }
  113.  puts("");
  114. }
  115. int main()
  116. {
  117.  while( scanf("%d", &n) == 1)
  118.  {
  119.   int i,x1,x2,c;
  120.   clr(a);
  121.   memset(b,-1,sizeof(b));
  122.   clr(num);
  123.   build(1,0,M);
  124.   for(i=0;i<n;i++)
  125.   {
  126.    scanf("%d%d%d",&x1,&x2,&c);
  127.    insert(1,x1,x2,c);
  128.    //int(1);
  129.    //ow(b,10);
  130.    //memset(b,-1,sizeof(b));
  131.    //printf("%d %d %d/n", x1,x2,c);
  132.   }
  133.   cal();
  134.   print();
  135.  }
  136.     return 0;
  137. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值