hdu 4027 Can you answer these queries?

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

  【更新区间,查询区间】的线段树,必须抓住修改6次以后每个数必然会变成1,然后以后的修改都将不起作用,在此之前的更新都是暴力更新。这是相当简单的题!

  我的做法是记录那些区间里的数都是小于2的,然后在更新的时候就不必更新那那些区间了。不过这题在数据格式中有个小trick,就是给出的区间范围的两个指针x可以大于y,这时在区间修改之前要交换回来。我就是在这个惯性思维的小trick上卡了一个下午。。。。。囧!

View Code
  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cmath>
  4 #include <cassert>
  5 #include <algorithm>
  6 
  7 #define lson l, m, rt << 1
  8 #define rson m + 1, r, rt << 1 | 1
  9 
 10 using namespace std;
 11 const int maxn = 100001;
 12 typedef __int64 ll;
 13 
 14 bool st[maxn << 2];
 15 ll sum[maxn << 2];
 16 
 17 void up(int rt){
 18     sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
 19     st[rt] = st[rt << 1] && st[rt << 1 | 1];
 20 }
 21 
 22 void build(int l, int r, int rt){
 23     if (l == r){
 24         scanf("%I64d", &sum[rt]);
 25         assert(sum[rt] >= 0);
 26         st[rt] = (sum[rt] < 2);
 27 
 28         return ;
 29     }
 30     int m = (l + r) >> 1;
 31 
 32     build(lson);
 33     build(rson);
 34     up(rt);
 35 }
 36 
 37 void update(int L, int R, int l, int r, int rt){
 38     if (L <= l && r <= R && st[rt]){
 39         return ;
 40     }
 41     if (l == r){
 42         sum[rt] = (ll) sqrt((double)sum[rt]);
 43         st[rt] = (sum[rt] < 2);
 44 
 45         return ;
 46     }
 47     int m = (l + r) >> 1;
 48 
 49     if (L <= m) update(L, R, lson);
 50     if (m < R) update(L, R, rson);
 51     up(rt);
 52 }
 53 
 54 ll query(int L, int R, int l, int r, int rt){
 55     if (L <= l && r <= R){
 56         return sum[rt];
 57     }
 58     ll ret = 0;
 59 
 60     int m = (l + r) >> 1;
 61 
 62     if (L <= m){
 63         ret += query(L, R, lson);
 64     }
 65     if (m < R){
 66         ret += query(L, R, rson);
 67     }
 68 
 69     return ret;
 70 }
 71 
 72 int main(){
 73     int n, m, cc = 0;
 74 #ifndef ONLINE_JUDGE
 75     freopen("in", "r", stdin);
 76 #endif
 77     while (~scanf("%d", &n)){
 78         build(1, n, 1);
 79         cc++;
 80 
 81         scanf("%d", &m);
 82         printf("Case #%d:\n", cc);
 83         while (m--){
 84             int op, l, r;
 85 
 86             scanf("%d%d%d", &op, &l, &r);
 87             if (op){
 88                 if (r < l) swap(l, r);
 89                 assert(l <= r);
 90                 printf("%I64d\n", query(l, r, 1, n, 1));
 91             }
 92             else{
 93                 if (r < l) swap(l, r);
 94                 assert(l <= r);
 95                 update(l, r, 1, n, 1);
 96             }
 97         }
 98         puts("");
 99     }
100 
101     return 0;
102 }

——written by Lyon

原文地址:https://www.cnblogs.com/LyonLys/p/hdu_4027_Lyon.html