1. 程式人生 > 其它 >hdu 4027 Can you answer these queries?

hdu 4027 Can you answer these queries?

技術標籤:線段樹演算法

題目:
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; }