題意:
給定100000個數,兩種操作,
0 i j表示將i j這段的數字都開根號(向下取整)
1 i j表示查詢i j之間的所有值的和
所有的和都不超過64位
思路:如果直接用線段樹更新會tle,此題的關鍵是要理解對任何64位以內的值,開根號最多不會超過7次,所以用線段樹做,更新到葉子節點的次數最多7次,如果葉子節點已經更新為1了,那麼再開根號也不會變了。
#include #include #include #include #define lson root<<1, l, mid
#define rson root<<1|1, mid+1, r
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
const int maxn = 100000+5;
ll tree[maxn<<2];
void push_up(int root)
void stree_build(int root, int l, int r)
int mid = (l+r) >> 1;
stree_build(lson);
stree_build(rson);
push_up(root);
}void update(int la, int rb, int l, int r, int root)
int mid = (l+r) >> 1;
if(la <= mid)
update(la, rb, l, mid, root<<1);
if(rb > mid)
update(la, rb, mid+1, r, root<<1|1);
push_up(root);
}ll ans;
void query(int la, int rb, int l, int r, int root)
if(l == r) return;
int mid = (l+r) >> 1;
if(la <= mid)
query(la, rb, l, mid, root<<1);
if(rb > mid)
query(la, rb, mid+1, r, root<<1|1);
push_up(root);
}int main()
else
} printf("\n");
} return 0;
}
HDU 4027 線段樹區間開根號
這道線段樹的題目我並沒有按照線段樹的模板寫,這裡把要點講出來就行了。第一 區間開根號不像區間乘或者除,能通過區間和然後一次性乘除求出乙個區間的乘除,所以區間開根號只能乙個乙個的開,但是如果乙個乙個的開不會超時嗎?假設乙個數在long long的範圍裡面,也就是2 63這個範圍內,那麼對這個數開根號最...
hdu 4027 線段樹區間開方求和
本來很早就做了這道題的,但是今天突然發現了.傳送門 解法 首先這道題的資料就告訴我們只能用線段樹,但區間操作似乎很蛋疼,我當時想的是用lazy標記記錄這段區間要開方幾次,等query時在統一進行單點更新,然後 我就t了,如果update一次query一次,我的lazy標記便並卵了,所以我們需要想更好...
HDU 4037 線段樹 區間開根號
區間開根號是不具備整體性的,即和開根號不一定等於開根號的和。但是由於由於在longlong範圍內的數開根號7次就會變成一所以我們單點更新也是可以的,剪枝就是如果乙個區間的和等於區間的大小就不用再繼續向下更新了,實現也簡單 ps 再注意幾個坑,每組樣例結束要多輸出乙個空行,and l,r的大小不確定 ...