hdu 4973 A simple simulation problem. (线段树)

题目链接

题意:

给定n长的序列 m个操作

序列默认为 1, 2, 3···n

操作1:D [l,r] 把[l,r]区间增长 :( 1,2,3,4 进行 D [1,3]变成 1,1,2,2,3,3,4 )

操作2:Q [l,r] 问区间[l,r] 上出现最多次数的数 的次数

分析:

会线段树,但是做题的时候没想到如何把这个处理,这是问题的关键。

当时比赛的时候卡了一题,然后快结束的时候看的这个题,所以很乱,没有想出来。

赛后, 我自己有写了一遍,但是我很sb的吧中间的一个变量写错了,结果错了好几天。

 

今天看别人的题解的时候,他们有加了一个lz【】延迟标记的,就是更新的时候更新到一整个区间的时候,就停止。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cmath>
 6 #include <algorithm>
 7 #define LL __int64
 8 #define lson l, mid, 2*rt
 9 #define rson mid+1, r, 2*rt+1
10 const int maxn = 50000+10;
11 using namespace std;
12 LL cnt[4*maxn], mx[4*maxn];
13 
14 void pushup(LL rt)
15 {
16     cnt[rt] = cnt[2*rt]+cnt[2*rt+1];
17     mx[rt] = max(mx[2*rt], mx[2*rt+1]);
18 }
19 void build(LL l, LL r, LL rt)
20 {
21     if(l==r)
22     {
23         cnt[rt] = 1;
24         mx[rt] = 1;
25         return;
26     }
27     int mid = (l+r)/2;
28     build(lson);
29     build(rson);
30     pushup(rt);
31 }
32 void update(LL ll, LL rr, LL l, LL r, LL rt) //每次更新到底
33 {
34     if(l==r)
35     {
36         cnt[rt] += (rr-ll+1);
37         mx[rt] = cnt[rt];
38         return;
39     }
40     int mid = (l+r)/2;
41     LL tmp = cnt[2*rt];   //就是这个变量写错了,错了好几天
42                           //还有这里一定要提前记录下cnt[2*rt],因为递归以后cnt[2*rt]的值会改变。
43     if(tmp>=rr)      update(ll, rr, lson);
44     else if(tmp<ll)  update(ll-tmp, rr-tmp, rson);
45     else
46     {
47         update(ll, tmp, lson);
48         update(1, rr-tmp, rson);
49     }
50     pushup(rt);
51 }
52 LL query(LL ll, LL rr, LL l, LL r, LL rt)
53 {
54     if(cnt[rt]==(rr-ll+1)) //查找的时候如果发现个数和那个区间的个数相同就是 区间都覆盖了
55     return mx[rt];
56     if(l==r)
57     return (rr-ll+1);
58 
59     int mid = (l+r)/2;
60     LL tmp = cnt[2*rt];
61 
62     if(tmp>=rr) return query(ll, rr, lson);
63     else if(tmp<ll) return query(ll-tmp, rr-tmp, rson);
64     else return max(query(ll, tmp, lson), query(1, rr-tmp, rson));
65 }
66 int main()
67 {
68     int t, ca = 1;
69     LL n, m;
70     LL l, r;
71     char ch;
72     scanf("%d", &t);
73     while(t--)
74     {
75         memset(mx, 0, sizeof(mx));
76         memset(cnt, 0, sizeof(cnt));
77         scanf("%I64d%I64d", &n, &m);
78         build(1, n, 1);
79         printf("Case #%d:\n", ca++);
80         while(m--)
81         {
82             getchar();
83             scanf("%c %I64d %I64d", &ch, &l, &r);
84             if(ch=='D')
85             update(l, r, 1, n, 1);
86             else
87             printf("%I64d\n", query(l, r, 1, n, 1));
88         }
89     }
90     return 0;
91 }

 

posted @ 2014-08-26 20:03  水门  阅读(221)  评论(0编辑  收藏  举报