題目:月下「毛景樹」
解析:樹鏈剖分。
注意一下線段樹的標記下傳的問題,先下傳覆蓋標記再下傳增加標記,且下傳覆蓋標記後要將增加標記取消。詳見**。
算了還是說下問什麼這樣下傳標記吧。
如果先下傳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 月下「毛景樹」
演算法 樹鏈剖分 線段樹 題解 線段樹的區間加值和區間覆蓋操作不能同時存在,只能存在乙個。修改 從根節點跑到目標區域路上的標記全部下傳,打完標記再上傳回根節點 有變動才需要上傳 詢問 訪問到目標區域路上的標記全部下傳。我寫的線段樹版本是在打標記的同時便對該點的詢問項 最大值 做了對應更改,即可保證訪...