hdu 4027 Can you answer these queries?
阿新 • • 發佈:2021-01-29
題目:
hdu
題意:
這句話的意思是sqrt後向下取整,而不是sqrt後四捨五入…
思路:
線段樹 + lazy(向上展開),如果sqrt到1後就不用sqrt了
程式碼
#include <iostream>
#include <algorithm>
#include <cmath>
#define ll long long
#define lson l, mid, pos << 1
#define rson mid + 1, r, pos << 1 | 1
using namespace std;
const int MAXN = 1e5 + 10;
ll tree[MAXN<<2];
bool lazy[MAXN<<2];
void updata(int p){
tree[p] = tree[p<<1] + tree[p<<1|1];
}
void lazyopen(int p){
if (lazy[p<<1] && lazy[p<<1|1])
lazy[p] = true;
}
void build(int l, int r, int pos){
lazy[pos] = false;
if (l == r){
scanf("%lld", &tree[pos]);
if (tree[pos] == 1)
lazy[pos] = true;
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
updata(pos);
lazyopen(pos);
}
void add(int L, int R, int l, int r, int pos){
if (l == r){
tree[pos] = (ll)floor(sqrt (tree[pos]*1.0)); //tree[pos] = sqrt(tree[pos]*1.0);
if (tree[pos] == 1)
lazy[pos] = true;
return;
}
//lazyopen(pos); 不能在這lazy展開,這裡用的lazy是向上展開而不是向下展開
int mid = (l + r) >> 1;
if (mid >= L && !lazy[pos<<1])
add(L, R, lson);
if (mid < R && !lazy[pos<<1|1])
add(L, R, rson);
updata(pos);
lazyopen(pos); //注意lazy展開在程式碼中的位置
}
ll find(int L, int R, int l, int r, int pos){ //這裡不像lazy向下展開,查詢函式沒有lazy展開
if (l >= L && r <= R)
return tree[pos];
//lazyopen(pos); 不能在這lazy展開
int mid = (l + r) >> 1;
ll ans = 0;
if (mid >= L)
ans += find(L, R, lson);
if (mid < R)
ans += find(L, R, rson);
return ans;
}
int main(){
int n, m, op, a, b, t = 0;
while (~scanf("%d", &n)){
printf("Case #%d:\n", ++t);
build(1, n, 1);
scanf("%d", &m);
while (m--){
scanf("%d%d%d", &op, &a, &b);
if (a > b)
swap(a, b); //這是個坑
if (op == 0)
add(a, b, 1, n, 1);
else
printf("%lld\n", find(a, b, 1, n, 1));
}
printf("\n"); //這是個坑
}
return 0;
}