[SPOJ-GSS4]Can you answer these queries IV 题解
题目地址:SPOJ:SPOJ.com – Problem GSS4、洛谷:【SP2713】GSS4 – Can you answer these queries IV – 洛谷
题目描述
You are given a sequence A of N(N <= 100,000) positive integers. There sum will be less than 10^18 . On this sequence you have to apply M (M <= 100,000) operations:
(A) For given x,y, for each elements between the x-th and the y-th ones (inclusively, counting from 1), modify it to its positive square root (rounded down to the nearest integer).
(B) For given x,y, query the sum of all the elements between the x-th and the y-th ones (inclusively, counting from 1) in the sequence.
题意简述
给你一个序列,两种操作:
- 区间每个数开方
- 区间求和
输入输出格式
输入格式:
Multiple test cases, please proceed them one by one. Input terminates by EOF.
For each test case:
The first line contains an integer N. The following line contains N integers, representing the sequence A1 .. AN.
The third line contains an integer M. The next M lines contain the operations in the form “i x y”.i=0 denotes the modify operation, i=1 denotes the query operation.
输出格式:
For each test case:
Output the case number (counting from 1) in the first line of output. Then for each query, print an integer as the problem required.
Print an blank line after each test case.
See the sample output for more details.
输入输出样例
输入样例#1:
5 1 2 3 4 5 5 1 2 4 0 2 4 1 2 4 0 4 5 1 1 5 4 10 10 10 10 3 1 1 4 0 2 3 1 1 4
输出样例#1:
Case #1: 9 4 6 Case #2: 40 26
题解
和[BZOJ3038]上帝造题的七分钟2是一个题。
代码
// Code by KSkun, 2018/6
#include <cstdio>
#include <cctype>
#include <cmath>
#include <algorithm>
typedef long long LL;
const int MAXN = 100005;
int n, m;
LL a[MAXN], sum[MAXN << 2], mx[MAXN << 2];
#define lch o << 1
#define rch o << 1 | 1
#define mid ((l + r) >> 1)
inline void build(int o, int l, int r) {
if(l == r) {
mx[o] = sum[o] = a[l]; return;
}
build(lch, l, mid);
build(rch, mid + 1, r);
sum[o] = sum[lch] + sum[rch];
mx[o] = std::max(mx[lch], mx[rch]);
}
inline void modify(int o, int l, int r, int ll, int rr) {
if(l == r) {
mx[o] = sum[o] = sqrt(sum[o]); return;
}
if(ll <= mid && mx[lch] > 1) modify(lch, l, mid, ll, rr);
if(rr > mid && mx[rch] > 1) modify(rch, mid + 1, r, ll, rr);
sum[o] = sum[lch] + sum[rch];
mx[o] = std::max(mx[lch], mx[rch]);
}
inline LL query(int o, int l, int r, int ll, int rr) {
if(l >= ll && r <= rr) return sum[o];
LL res = 0;
if(ll <= mid) res += query(lch, l, mid, ll, rr);
if(rr > mid) res += query(rch, mid + 1, r, ll, rr);
return res;
}
int op, l, r;
int main() {
int kase = 0;
while(scanf("%d", &n) != EOF) {
printf("Case #%d:\n", ++kase);
for(int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
}
build(1, 1, n);
scanf("%d", &m);
while(m--) {
scanf("%d%d%d", &op, &l, &r);
if(l > r) std::swap(l, r);
if(op == 0) {
modify(1, 1, n, l, r);
} else {
printf("%lld\n", query(1, 1, n, l, r));
}
}
puts("");
}
return 0;
}