[BZOJ3211] 花神游历各国 - 线段树
3211: 花神游历各国
Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 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
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
11
11
HINT
对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9
Source
题解:
直接线段树大力维护, 在遇到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 }