[BZOJ3211] 花神游历各国 - 线段树

3211: 花神游历各国

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 4766  Solved: 1741
[Submit][Status][Discuss]

Description

 

Input

 

Output

每次x=1时,每行一个整数,表示这次旅行的开心度

Sample Input

4

1 100 5 5

5

1 1 2

2 1 2

1 1 2

2 2 3

1 1 4

Sample Output

101

11

11

HINT

对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9


Source

SPOJ2713 gss4 数据已加强


 

 

提交地址BZOJ   LUOGU

 


 

 

题解:

直接线段树大力维护, 在遇到0或者1的时候可以直接不用管;

如果子树都为1或0,它也不用管;

 

 


 

 

Code

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 using namespace std;
 5 
 6 int n, m;
 7 long long a[100005];
 8 
 9 struct SegMent
10 {
11     int l, r;
12     long long sum;
13     bool flag;
14 }tr[100005*4];
15 
16 #define ls(x) x << 1
17 #define rs(x) x<<1|1
18 #define sum(x) tr[x].sum
19 #define flag(x) tr[x].flag
20 
21 inline void build(int o, int l, int r)
22 {
23     if (l == r) 
24     {
25         sum(o) = a[l];
26         tr[o].l = tr[o].r = l;
27         if (a[l] == 1 or a[l] == 0) flag(o) = 1;
28         return;
29     }
30     int mid = l + r >> 1;
31     build(ls(o), l, mid);
32     build(rs(o), mid + 1, r);
33     sum(o) = sum(rs(o)) + sum(ls(o));
34     flag(o) = flag(rs(o)) & flag(ls(o));
35     tr[o].l = tr[ls(o)].l;
36     tr[o].r = tr[rs(o)].r;
37 }
38 
39 inline void change(int o, int l, int r)
40 {
41     if (flag(o)) return;
42     if (tr[o].l == tr[o].r) 
43     {
44         sum(o) = (long long)sqrt(sum(o));
45         if (sum(o) == 1 or sum(o) == 0) flag(o) = 1;
46         return;
47     }
48     int mid = tr[o].l + tr[o].r >> 1;
49     if (l <= mid) change(ls(o), l, r);
50     if (r > mid) change(rs(o), l, r);
51     sum(o) = sum(rs(o)) + sum(ls(o));
52     flag(o) = flag(ls(o)) & flag(rs(o));
53 }
54 
55 inline long long query(int o, int l, int r)
56 {
57     if (tr[o].l >= l and tr[o].r <= r) return sum(o);
58     long long res = 0;
59     int mid = tr[o].l + tr[o].r >> 1;
60     if (l <= mid) res += query(ls(o), l, r);
61     if (r > mid) res += query(rs(o), l, r);
62     return res;
63 }
64 
65 int main()
66 {
67     scanf("%d", &n);
68     for (register int i = 1 ; i <= n ; i ++) scanf("%lld",&a[i]);
69     build(1, 1, n);
70     scanf("%d", &m);
71     while (m--)
72     {
73         int opt, x, y;
74         scanf("%d%d%d", &opt, &x, &y);
75         if (x > y) swap(x, y);
76         if (opt == 1) printf("%lld\n", query(1, x, y));
77         else change(1, x, y);
78     }
79     return 0;
80 }

 

posted @ 2018-06-09 21:36  zZhBr  阅读(150)  评论(0编辑  收藏  举报