SPOJ GSS4 Can you answer these queries IV

来源:互联网 发布:如何练好字 知乎 编辑:程序博客网 时间:2024/06/06 00:46

题意:

给定一个序列和m个操作,

1,让l~r区间内的数都开方

2,求区间和。

思路:

由于LL内的数最多开方10次就会变成1了, 所以用区间维护区间和, 然后开方的时候如果不是全都是1的话就暴力开方, 区间内全都是1的话就不更新。

这么搞不是很靠谱的感觉。。用线段树套平衡树可以做到mlognlogn。。 但是懒得写了。。。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;#define LL long long#define N 100020#define ls (i << 1)#define rs (ls | 1)#define md ((ll + rr) >> 1)#define lson ll, md, ls#define rson md + 1, rr, rsint n;LL sum[N*4];void push_up(int i) {sum[i] = sum[ls] + sum[rs];}void build(int ll, int rr, int i) {if(ll == rr) {scanf("%lld", &sum[i]);return;}build(ll, md, ls);build(md + 1, rr, rs);push_up(i);}void update(int l, int r, int ll, int rr, int i) {if(sum[i] == rr - ll + 1)return;if(ll == rr) {sum[i] = sqrt(sum[i] + 0.5);return;}if(r <= md) update(l, r, lson);else if(l > md) update(l, r, rson);elseupdate(l, md, lson), update(md + 1, r, rson);push_up(i);}LL query(int l, int r, int ll, int rr, int i) {if(ll == l && rr == r) return sum[i];if(r <= md) return query(l, r, lson);if(l > md) return query(l, r, rson);return query(l, md, lson) + query(md + 1, r, rson);}int main() {int kk = 0;while(scanf("%d", &n) != EOF) {build(1, n, 1);int m;scanf("%d", &m);printf("Case #%d:\n", ++kk);while(m--) {int op, l, r;scanf("%d%d%d", &op, &l, &r);if(l > r) swap(l, r);if(op == 0)update(l, r, 1, n, 1);elseprintf("%lld\n", query(l, r, 1, n, 1));}puts("");}return 0;}


0 0
原创粉丝点击