BZOJ1984 月下「毛景樹」

2021-08-30 04:43:52 字數 1650 閱讀 9356

題目:月下「毛景樹」

解析:樹鏈剖分。

注意一下線段樹的標記下傳的問題,先下傳覆蓋標記再下傳增加標記,且下傳覆蓋標記後要將增加標記取消。詳見**。

算了還是說下問什麼這樣下傳標記吧。

如果先下傳add再下傳cover,你會發現對於修改同一區間,操作順序是先add再cover時下傳沒有問題,但如果是先cover再add就出問題了,由於先下傳add,所以修改後還是原來的數增加,而不是cover後增加的,所以很不方便處理。

如果先下傳cover再下傳add,那麼如果在下傳cover的過程中把原來的add標記取消,那麼操作順序是先add再cover時下傳沒有問題,如果是先cover再add,由於把原來的add標記取消了,所以直接加上新的add標記就行了,正確性顯然。

所以對於線段樹的標記下傳要仔細考慮順序,什麼順序更好處理,正確效能不能保證。

ps:今天真是不宜oi,這題坑了我一晚上最終是q部分沒有標記下傳。。。

**:

#include using namespace std;

const int max=100005;

int n,m,tot,s;

int u[max],v[max],first[max],id[max];

int num[max],size[max],fa[max],dep[max],top[max],son[max],rev[max],seg[max];

int tree[max<<2],add[max<<2],cover[max<<2];

struct shuedge[max<<1];

char ch[10];

inline int get_int()

inline void print(int x)

inline int max(int a,int b)

}inline void dfs2(int p,int tp)}//

inline void pushc(int root,int x)

inline void pusha(int root,int x)

inline void pushdown(int root)

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

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

buildtree(root<<1,l,mid),buildtree(root<<1|1,mid+1,r);

tree[root]=max(tree[root<<1],tree[root<<1|1]);

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

inline void cover(int root,int l,int r,int l,int r,int x)

inline int q(int root,int l,int r,int l,int r)

//inline void modify(int x,int y,int k,int typ)

inline int ask(int x,int y)

//int main()

else if(ch[0]=='a')

else print(ask(x,y)),putchar('\n');

} return 0;

}

BZOJ1984 月下「毛景樹」

time limit 20 sec memory limit 64 mb submit 1583 solved 500 submit status discuss 毛毛蟲經過及時的變形,最終逃過的一劫,離開了菜媽的菜園。毛毛蟲經過千山萬水,歷盡千辛萬苦,最後來到了小小的紹興一中的校園裡。爬啊爬 爬啊...

bzoj1984 月下「毛景樹」

傳送門 果然強校出的題都有坑 好吧其實是我太弱 都知道化邊權為點權了還沒發現鏈上查詢和修改時的坑 知道了這個這題就是板子題了 code include includeusing namespace std define n 100005 struct tree t n 2 int f n deep ...

BZOJ 1984 月下「毛景樹」

演算法 樹鏈剖分 線段樹 題解 線段樹的區間加值和區間覆蓋操作不能同時存在,只能存在乙個。修改 從根節點跑到目標區域路上的標記全部下傳,打完標記再上傳回根節點 有變動才需要上傳 詢問 訪問到目標區域路上的標記全部下傳。我寫的線段樹版本是在打標記的同時便對該點的詢問項 最大值 做了對應更改,即可保證訪...