HDU4027 Can you answer these queries?

  原题传送:http://acm.hdu.edu.cn/showproblem.php?pid=4027

  线段树。

  一个很大的数(< 263),最多也就进行几次开平方操作就会达到1了,所以每次更新,如果区间有的点不为1,那么就直接更新它,如果,区间的值都是1了,那么必须直接返回。

View Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 #include <stdlib.h>
 5 #define lson (cur << 1)
 6 #define rson (cur << 1 | 1)
 7 #define N 100005
 8 #define LL __int64
 9 
10 int n, m;
11 LL a[N];
12 LL tree[N << 2];  // 记录区间最大值,如果最大值为1,说明该区间值全为1
13 LL sum[N << 2];
14 
15 inline LL max(LL x, LL y){return x > y ? x : y;}
16 inline void swap(int &x, int &y){int tmp = x; x = y; y = tmp;}
17 
18 void pushup(int cur)
19 {
20     tree[cur] = max(tree[lson], tree[rson]);
21     sum[cur] = sum[lson] + sum[rson];
22 }
23 
24 void update(int cur, int l, int r, int s, int t)
25 {
26     if(tree[cur] == 1)
27         return ;
28     if(l == r)
29     {
30         tree[cur] = (LL)sqrt((double)tree[cur]);
31         sum[cur] = tree[cur];
32         return ;
33     }
34     int mid = (l + r) >> 1;
35     if(mid >= s)
36         update(lson, l, mid, s, t);
37     if(mid < t)
38         update(rson, mid + 1, r, s, t);
39     pushup(cur);
40 }
41 
42 void query(int cur, int l, int r, int s, int t, LL &ans)
43 {
44     if(l >= s && r <= t)
45     {
46         ans += sum[cur];
47         return ;
48     }
49     int mid = (l + r) >> 1;
50     if(mid >= s)
51         query(lson, l, mid, s, t, ans);
52     if(mid + 1 <= t)
53         query(rson, mid + 1, r, s, t, ans);
54 }
55 
56 void build(int cur, int l, int r)
57 {
58     if(l == r)
59     {
60         sum[cur] = tree[cur] = a[l];
61         return ;
62     }
63     int mid = (l + r) >> 1;
64     build(lson, l, mid);
65     build(rson, mid + 1, r);
66     pushup(cur);
67 }
68 
69 int main()
70 {
71     int i, op, x, y, cas = 1;
72     LL ans;
73     while(scanf("%d", &n) != EOF)
74     {
75         for(i = 1; i <= n; i ++)
76             scanf("%I64d", &a[i]);
77         build(1, 1, n);
78         scanf("%d", &m);
79         printf("Case #%d:\n", cas ++);
80         while(m --)
81         {
82             scanf("%d%d%d", &op, &x, &y);
83             if(x > y) swap(x, y);   // !
84             if(op == 0)
85             {
86                 update(1, 1, n, x, y);
87             }
88             else if(op == 1)
89             {
90                 ans = 0;
91                 query(1, 1, n, x, y, ans);
92                 printf("%I64d\n", ans);
93             }
94         }
95         putchar('\n');
96     }
97     return 0;
98 }
posted @ 2012-10-02 22:09  芒果布丁  阅读(154)  评论(0编辑  收藏  举报