码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4391 线段树+优化

时间:2015-03-31 00:51:04      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:

Paint The Wall

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2783    Accepted Submission(s): 766


Problem Description
As a amateur artist, Xenocide loves painting the wall. The wall can be considered as a line consisting of n nodes. Each node has its own color.

Xenocide spends all day in front of the wall. Sometimes, he paints some consecutive nodes so that these nodes have the same color. When he feels tired, he focuses on a particular color and counts the number of nodes that have this color within a given interval.

Now Xenocide is tired of counting, so he turns to you for help.
 

 

Input
The input consists of several test cases.
The first line of each test case contains two integer n, m(1<=n, m<=100000) indicating the length of the wall and the number of queries.
The following line contains N integers which describe the original color of every position.
Then m lines follow. Each line contains 4 non-negative integers a, l, r, z(1<=a<=2, 0<=l<=r<n ,0<=z<231).
a = 1 indicates that Xenocide paints nodes between l and r and the resulting color is z.
a = 2 indicates that Xenocide wants to know how many nodes between l and r have the color z.
 

 

Output
Print the corresponding answer for each queries.
 

 

Sample Input
5 5
1 2 3 4 0
2 1 3 3
1 1 3 1
2 1 3 3
2 0 3 1
2 3 4 1
 

 

Sample Output
1
0
4
1
 

 

Source
 
 
题目意思:
在0-n-1区间内每个点都有一个初始颜色,有两种操作,1 l r w表示更新l-r区间为w颜色,2 l r w表示查找l-r区间颜色为w点的数目。
 
思路:
很明显是线段树,但是普通的线段树会超时,我报着试一试的心态写了个线段树果然超时了。。。我发现超时的原因应该是颜色太多了。。那么若一个区间内没有颜色为w的点,还是需要查找到叶子,那么必定超时的。
所以加了优化,记录每个区间的颜色范围,若查找的颜色没在这个区间,那么就return 0。
然后就AC了。
我看了看网上代码基本上和我思路一样,有人说这道题根本不是线段树,而是分段哈希。。分块?。。。好吧。。我承认我不会,接下来就学习正解吧。。。
 
代码:
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 #include <queue>
 7 #include <cmath>
 8 #include <set>
 9 using namespace std;
10 
11 #define N 100005
12 #define ll root<<1
13 #define rr root<<1|1
14 #define mid (a[root].l+a[root].r)/2
15 int max(int x,int y){return x>y?x:y;}
16 int min(int x,int y){return x<y?x:y;}
17 int abs(int x,int y){return x<0?-x:x;}
18 
19 struct node{
20     int l, r, val;
21     int maxh, minh;
22     bool flag;
23 }a[N*4];
24 
25 int b[N];
26 int n, m;
27 
28 void build(int l,int r,int root){
29     a[root].l=l;
30     a[root].r=r;
31     a[root].flag=false;
32     if(l==r){
33         a[root].flag=true;
34         a[root].maxh=a[root].minh=a[root].val=b[l];return;
35     }
36     build(l,mid,ll);
37     build(mid+1,r,rr);
38     a[root].maxh=max(a[ll].maxh,a[rr].maxh);
39     a[root].minh=min(a[ll].minh,a[rr].minh);
40 }
41 
42 void update(int l,int r,int val,int root){
43     if(a[root].flag&&a[root].l!=a[root].r){
44         a[ll].flag=a[rr].flag=true;
45         a[ll].maxh=a[ll].minh=a[rr].maxh=a[rr].minh=a[ll].val=a[rr].val=a[root].val;
46         a[root].flag=false;
47     }
48     if(a[root].l==l&&a[root].r==r){
49         a[root].val=val;
50         a[root].flag=true;
51         a[root].maxh=a[root].minh=val;
52         return;
53     }
54     if(l>mid) update(l,r,val,rr);
55     else if(r<=mid) update(l,r,val,ll);
56     else{
57         update(l,mid,val,ll);
58         update(mid+1,r,val,rr);
59     }
60     if(a[ll].val==a[rr].val&&a[ll].flag&&a[rr].flag){
61         a[root].flag=true;
62         a[root].val=a[ll].val;
63     }
64     a[root].maxh=max(a[ll].maxh,a[rr].maxh);
65     a[root].minh=min(a[ll].minh,a[rr].minh);
66 }
67 
68 int ans;
69 
70 int query(int l,int r,int val,int root){
71     if(a[root].flag&&a[root].val!=val) return 0;
72     if(a[root].flag&&a[root].val==val) return r-l+1;
73     if(a[root].l==a[root].r) return 0;
74     if(a[root].maxh<val||a[root].minh>val) return 0;
75     if(l>mid) return query(l,r,val,rr);
76     else if(r<=mid) return query(l,r,val,ll);
77     else return query(l,mid,val,ll)+query(mid+1,r,val,rr);
78 }
79 
80 main()
81 {
82     int x, y, z, w;
83     int i, j, k;
84     while(scanf("%d %d",&n,&m)==2){
85         for(i=0;i<n;i++) scanf("%d",&b[i]);
86         build(0,n-1,1);
87         while(m--){
88             scanf("%d %d %d %d",&x,&y,&z,&w);
89             if(x==1){
90                 update(y,z,w,1);
91             }
92             else{
93                 int ans=query(y,z,w,1);
94                 printf("%d\n",ans);
95             }
96         }
97     }
98 }

 

HDU 4391 线段树+优化

标签:

原文地址:http://www.cnblogs.com/qq1012662902/p/4379607.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!