hdu 4391 Paint The Wall 线段树 +优化 2012 Multi-University Training Contest 10 )

http://acm.hdu.edu.cn/showproblem.php?pid=4391

题意:

刷墙, 以开始 有 n个节点,每个节点有一种颜色 ,m 次询问

 m次  输入 a,l,r,z 如果 a=1 将 l到 r 刷为 z 颜色,如果 a=2  询问 l 到 r 有 多少个 和 z 相同的 节点

官方题解是: 分段哈希,自己一开始想写 一下 ,单写着写着 就 觉得很麻烦 ,各中判断条件。。。。。

后来改为 线段树  优化了下 ,就是加了 个 mi mx  判断 查询的颜色 是否在这里面。。。。。

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include< set>
  7 #include<map>
  8 #include<queue>
  9 #include<vector>
 10 #include< string>
 11  #define Min(a,b) a<b?a:b
 12  #define Max(a,b) a>b?a:b
 13  #define CL(a,num) memset(a,num,sizeof(a));
 14  #define maxn  100010
 15  #define eps  1e-6
 16  #define inf 9999999
 17  #define ll  __int64
 18  using  namespace std;
 19  struct node
 20 {
 21      int l;
 22      int r;
 23      int c;
 24      int mi;
 25      int mx;
 26 }p[maxn* 4];
 27  int a[maxn] ;
 28  void build( int x, int l, int r)
 29 {
 30      if(l == r)
 31     {
 32          p[x].l = l;
 33          p[x].r = r;
 34          p[x].c= a[l];
 35          p[x].mi = a[l];
 36          p[x].mx = a[l];
 37           return ;
 38     }
 39      int mid = (l+r)>> 1;
 40      p[x].l = l;
 41      p[x].r = r;
 42      build(x* 2,l,mid);
 43      build(x* 2+ 1,mid+ 1,r);
 44       if(p[x* 2].c == p[x* 2+ 1].c &&p[x* 2].c != - 1)p[x].c = p[x* 2].c;
 45       else p[x].c = - 1;
 46 
 47      p[x].mi = min(p[x* 2].mi,p[x* 2+ 1].mi);
 48      p[x].mx = max(p[x* 2].mx,p[x* 2+ 1].mx);
 49 
 50 
 51 
 52 }
 53  void change( int x, int l, int r, int z)
 54 {
 55      if(z == p[x].c)   return;
 56      if(l == p[x].l&&r == p[x].r)
 57     {
 58         p[x].c = z ;
 59         p[x].mi = z;
 60         p[x].mx = z;
 61 
 62          return  ;
 63 
 64     }
 65      int mid = (p[x].l+p[x].r)>> 1;
 66      if(p[x].c != - 1)
 67     {
 68         p[x* 2].c = p[x].c;
 69         p[x* 2+ 1].c = p[x].c;
 70         p[x* 2].mi =p[x* 2+ 1].mi = p[x].mi;//这两个忘了 下分了 错了 一次。。。。。。。。
 71         p[x* 2].mx=p[x* 2+ 1].mx = p[x].mx;
 72         p[x].c = - 1;
 73     }
 74 
 75      if(r<=mid) change(x* 2,l,r,z);
 76      else
 77     {
 78          if(l>mid)change(x* 2+ 1,l,r,z);
 79          else
 80         {
 81             change(x* 2,l,mid,z);
 82             change(x* 2+ 1,mid+ 1,r,z);
 83         }
 84     }
 85      p[x].mi = min(p[x* 2].mi,p[x* 2+ 1].mi);
 86      p[x].mx = max(p[x* 2].mx,p[x* 2+ 1].mx);
 87 }
 88  int  get( int x, int l, int r, int z)
 89 {
 90      if(p[x].c!=- 1 &&p[x].c!=z) return  0;
 91      if(z<p[x].mi ||z>p[x].mx)  return  0;
 92 
 93      if(p[x].l <= l&&p[x].r >= r&&p[x].c == z)
 94     {
 95          return r - l +  1;
 96     }
 97      int mid = (p[x].l + p[x].r)>> 1;
 98 
 99      if(r<=mid)  return  get(x* 2,l,r,z);
100      else
101     {
102          if(l>mid)  return  get(x* 2+ 1,l,r,z);
103          else
104         {
105              int t1 =  get(x* 2,l,mid,z);
106              int t2 =  get(x* 2+ 1,mid+ 1,r,z);
107              return t1+t2;
108         }
109     }
110 
111 
112 
113 }
114 
115  int main()
116 {
117      int n,m,d,l,r,z,i;
118     // freopen("data.in","r",stdin);
119       while(scanf( " %d%d ",&n,&m)!=EOF)
120     {
121          for(i =  0; i < n;i++)
122         {
123             scanf( " %d ",&a[i]);
124         }
125         build( 1, 0,n -  1);
126          while(m--)
127         {
128             scanf( " %d%d%d%d ",&d,&l,&r,&z);
129              if(d ==  1)
130             {
131                 change( 1,l,r,z);
132             }
133              else
134             {
135                  int ans =  get( 1,l,r,z);
136                 printf( " %d\n ",ans);
137             }
138         }
139     }
140 }

 

 

转载于:https://www.cnblogs.com/acSzz/archive/2012/08/24/2654564.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值