367 字
2 分钟
BZOJ 3211 花神游历各国
Description
Input
Output
每次x=1时,每行一个整数,表示这次旅行的开心度
Sample Input
41 100 5 551 1 22 1 21 1 22 2 31 1 4
Sample Output
1011111
题解
本题和上帝造题的七分钟是一样的
但我的程序没有过啊
打的比较傻
其实只要维护一个值就可以了
用一个flag标记是否不变
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;#ifndef LL#define LL long long#endif#define lch l, m, rt << 1#define rch m + 1, r, rt << 1 | 1const int N = 100005;LL Sum[N << 2];bool flag[N << 2];void PushUp(int rt){ Sum[rt] = Sum[rt << 1] + Sum[rt << 1 | 1]; flag[rt] = flag[rt << 1] & flag[rt << 1 | 1];}void buildtree(int l, int r, int rt){ if(l == r) { scanf("%lld", &Sum[rt]); if(Sum[rt] <= 1) flag[rt] = 1; return; } int m = l + r >> 1; buildtree(lch); buildtree(rch); PushUp(rt);}void Update(int L, int R, int l, int r, int rt){ if(flag[rt]) return; if(l == r) { Sum[rt] = sqrt(Sum[rt]); if(Sum[rt] <= 1) flag[rt] = 1; return; } int m = l + r >> 1; if (L <= m) Update(L, R, lch); if (R > m) Update(L, R, rch); PushUp(rt);}LL Query(int L, int R, int l, int r, int rt){ if(L <= l && R >= r) return Sum[rt]; int m = l + r >> 1; LL ans = 0; if (L <= m) ans += Query(L, R, lch); if (R > m) ans += Query(L, R, rch); return ans;}int main(){ int n; scanf("%d", &n); buildtree(1, n, 1); int m; scanf("%d", &m); while (m--) { int op, l, r; scanf("%d%d%d", &op, &l, &r); if(l > r) swap(l, r); if (op == 1) { printf("%lld\n", Query(l, r, 1, n, 1)); } else Update(l, r, 1, n, 1); }}