BZOJ 3211: 花神游历各国( 线段树 )

--------------------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>

#define rep(i, n) for(int i = 0; i < n; i++)
#define M(l, r) (((l) + (r)) >> 1)
#define clr(x, c) memset(x, c, sizeof(x))

using namespace std;

typedef long long ll;

const int maxn = 100009;

struct Node {
Node *l, *r;
int v, mx;
ll sum;
Node():mx(0) {
l = r = NULL;
}
inline void update() {
if(l) {
mx = max(l->mx, r->mx);
sum = l->sum + r->sum;
} else
sum = mx = v;
}
} pool[maxn << 1], *pt = pool, *root;

int L, R, n, seq[maxn];

void build(Node* t, int l, int r) {
if(r > l) {
int m = M(l, r);
build(t->l = pt++, l, m);
build(t->r = pt++, m + 1, r);
} else
t->v = seq[l];
t->update();
}

void modify(Node* t, int l, int r) {
if(t->mx <= 1) return;
if(l == r)
t->v = floor(sqrt(t->v));
else {
int m = M(l, r);
if(L <= m) modify(t->l, l, m);
if(m < R) modify(t->r, m + 1, r);
}
t->update();
}

ll query(Node* t, int l, int r) {
if(L <= l && r <= R)
return t->sum;
int m = M(l, r);
return (L <= m ? query(t->l, l, m) : 0 ) + (m < R ? query(t->r, m + 1, r) : 0);

int main() {
// freopen("test.in", "r", stdin);
cin >> n;
for(int i = 1; i <= n; i++)
scanf("%d", seq + i);
build(root = pt++, 1, n);
int m, op;
cin >> m;
while(m--) {
scanf("%d%d%d", &op, &L, &R);
if(op == 1)
printf("%lld\n", query(root, 1, n));
else
modify(root, 1, n);
}
return 0;
}

--------------------------------------------------------------------------------------------

3211: 花神游历各国

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 1414  Solved: 546
[Submit][Status][Discuss]

4

1 100 5 5

5

1 1 2

2 1 2

1 1 2

2 2 3

1 1 4

101

11

11

Source

posted @ 2015-07-20 11:23  JSZX11556  阅读(664)  评论(2编辑  收藏  举报