本來很早就做了這道題的,但是今天突然發現了.
傳送門:
解法:首先這道題的資料就告訴我們只能用線段樹,但區間操作似乎很蛋疼,我當時想的是用lazy標記記錄這段區間要開方幾次,等query時在統一進行單點更新,然後…….我就t了,如果update一次query一次,我的lazy標記便並卵了,所以我們需要想更好方法來解這道題.
每個數的範圍是int,且向下取整,這代表在少量操作後,它就會為一,所以我們只需要看這段區間的值是否為r-l+1,如果是,就continue,否則就單點更新,這樣的時間複雜度大約在nlogn左右.問題完美解決
#include
#include
#include
#include
#include
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using
namespace
std;
int sum[400005],n,m,x,l,r;
void pushup(int rt)
void build(int rt,int l,int r)
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}void update(int rt,int l,int r,int x,int y)
if (sum[rt]==r-l+1)
int mid=(l+r)>>1;
if (l<=mid) update(lson,x,y);
if (r>mid) update(rson,x,y);
pushup(rt);
}int query(int rt,int l,int r,int x,int y)
int mid=(l+r)>>1;
if(y<=mid) ans=query(lson,x,y);
else
if(x>mid) ans=query(rson,x,y);
else
pushup(rt);
}void readdata()
if (x==1)}}
}void o_o()
void t_t()
int main()
HDU 4027 線段樹區間開根號
這道線段樹的題目我並沒有按照線段樹的模板寫,這裡把要點講出來就行了。第一 區間開根號不像區間乘或者除,能通過區間和然後一次性乘除求出乙個區間的乘除,所以區間開根號只能乙個乙個的開,但是如果乙個乙個的開不會超時嗎?假設乙個數在long long的範圍裡面,也就是2 63這個範圍內,那麼對這個數開根號最...
Hdu4027 線段樹開根號區間求和
題意 給定100000個數,兩種操作,0 i j表示將i j這段的數字都開根號 向下取整 1 i j表示查詢i j之間的所有值的和 所有的和都不超過64位 思路 如果直接用線段樹更新會tle,此題的關鍵是要理解對任何64位以內的值,開根號最多不會超過7次,所以用線段樹做,更新到葉子節點的次數最多7次...
hdu4027 線段樹的lazy操作
剛開始的時候第一反應這道題是成段的更新,不能乙個數乙個數的更新,那樣肯定會超時的!但是再想了一會兒之後,發現成段更新比較困難,主要是這道題的每個節點的更新並不是統一的 也就是說並不是都加k,或者都減k之類的 所以我們並不能像一般的成段更新那樣去更新。再仔細觀察後,其實我們可以很容易的發現,乙個數k ...