UOJ228 基礎資料結構練習題

2022-05-08 04:57:08 字數 1694 閱讀 1674

作者部落格:

正解:線段樹

解題報告:

這道題是一道線段樹的神題,需要我們支援區間開方、區間加法和區間求和操作。

關鍵是對於開方操作的處理,考慮如果乙個區間最大值等於最小值(即全都相等),那麼就可以直接開方,然後區間賦值。

否則就往下遞迴處理,知道發現整個區間相等再區間操作。

上述做法在這樣的資料下會被卡tle:8、9、8、9,這樣每次都會達到最壞複雜度。

但是我們發現他們如果開方之後的減少的值是相同的,也就是說這種情況我們可以特判,變成區間減法操作,這樣就可以保證複雜度。

為了降低程式設計複雜度,可以把區間賦值操作變成區間減法,也就是負數的區間減法,會方便很多。

另外,標記可持久化+不下傳,可以大大減小常數。

//it is made by ljh2000

#include #include #include #include #include #include #include #include #include #define lc root<<1

#define rc root<<1|1

using namespace std;

typedef long long ll;

const int maxn = 100011;

int n,m,c[maxn],ql,qr,val;

ll ans;

struct nodea[maxn*3];

inline void jia(node &tmp,ll y)

inline int getint()

inline void update(int root)

inline void build(int root,int l,int r)

int mid=(l+r)>>1;

build(lc,l,mid);

build(rc,mid+1,r);

update(root);

}inline void add(int root,int l,int r)

int mid=(l+r)>>1;

if(ql<=mid) add(root<<1,l,mid);

if(qr>mid) add(root<<1|1,mid+1,r);

update(root);

}inline void sqr(int root,int l,int r,ll tag)

else if((a[root].max==a[root].min+1) && cp1==cp2)

} int mid=(l+r)>>1;

if(ql<=mid) sqr(lc,l,mid,tag+a[root].tag);

if(qr>mid) sqr(rc,mid+1,r,tag+a[root].tag);

update(root);

}inline void query(int root,int l,int r,ll tag)

int mid=(l+r)>>1;

if(ql<=mid) query(lc,l,mid,tag+a[root].tag);

if(qr>mid) query(rc,mid+1,r,tag+a[root].tag);

}inline void work()

else if(type==2)

else }}

int main()

uoj 228 基礎資料結構練習題

第一次看到這題大概在這裡 2016多校聯合 反正當時也沒什麼想法,表示有區間加好難受。題解並不難,維護每個區間最值 和,當乙個區間開根後所有值都一樣就直接賦值,否則遞迴。存在一種特例 3 4 3 4 3 4 3 4 3,開根後1 2 1 2 1 2 1 2 1.2 3 4 3 4 3 4 3 4 3...

題解 uoj228 基礎資料結構練習題

題目大意 給定乙個序列,要求支援區間加 區間開根號 區間求和操作。線段樹,我們可以像往常一樣判斷區間內的數是否都相等,如果相等就直接區間賦值,否則暴力遞迴下去。但是開根號還有一種特殊情況 3 4 3 4 3 4 開完根號1 2 1 2 1 2 同時加上2又變回了3 4 3 4 3 4 就給乙個完全平...

UOJ228 基礎資料結構練習題(線段樹)

給定序列,要求資瓷區間加 區間開根 區間求和。用線段樹維護最大值 最小值 和。如果 max max min min max max min min 那麼一起處理 打上區間減標記即可。時間複雜度?我太菜了,不知道。au hany01 prob uoj228 基礎資料結構練習題 date jul 31s...