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 }