hdu 4391 Paint The Wall 线段树 +优化 2012 MultiUniversity 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/p/2654564.html