luogu3384 樹鏈剖分

2021-07-24 12:22:49 字數 1304 閱讀 1338

辣雞題目毀我青春!

以前寫線段樹,指標從來不賦初值,偏偏這道題乖張,本來應該1a的題目我提交了29遍!我的ac率,我的時間!

呃,,吐槽完了。。還是自己習慣不好

輕重邊剖分之後每個點的tid其實就是它的dfs序。。tid陣列順著輸出其實就是樹的先序遍歷(允許我亂用概念吧),那麼以乙個節點為根節點的子樹就是剛進dfs時候的時間戳到退出這層dfs時的時間戳之內的節點。

//樹鏈剖分+dfs序

#include #include #define maxn 200010

using namespace std;

int n, m, r, p, l[maxn], r[maxn], tim, fa[maxn], size[maxn], son[maxn], tid[maxn],

head[maxn], next[maxn], to[maxn], val[maxn], w[maxn], tot, top[maxn], deep[maxn],

debug;

struct segtree

}*root;

void adde(int a, int b)

void pushdown(segtree *p)

void update(segtree *p)

void segadd(segtree *p, int l, int r, int d)

if(l<=mid)segadd(p->lch,l,r,d);

if(r>mid)segadd(p->rch,l,r,d);

update(p);

}int segsum(segtree *p, int l, int r)

if(l<=mid)ans=(ans+segsum(p->lch,l,r))%p;

if(r>mid)ans=(ans+segsum(p->rch,l,r))%p;

return ans;

}void build(segtree *p, int l, int r)

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

build(p->lch=new segtree,l,mid);

build(p->rch=new segtree,mid+1,r);

update(p);

}void dfs1(int pos)

}void dfs2(int pos, int tp)

r[pos]=tim;

}void init()

int sum(int a, int b)

int main()

return 0;

}

luogu3384 模板 樹鏈剖分

題目描述 如題,已知一棵包含n個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作1 格式 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z 操作2 格式 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和 操作3 格式 3 x z 表示將以x為根節點的子...

luogu3384 模板 樹鏈剖分

省選被暴虐,成功爆0。順便ditoly差點全省總分rank1 orz.於是開始趕進度學新演算法。然後決定開始學習樹剖orz。發現樹剖很好用啊!然後做了模板題。題目就是給你一棵樹,然後每次操作是查詢或者增加一條樹上2點路徑 子樹的值。期望時間效率 o m log log n 最壞時間複雜度 o m l...

樹鏈剖分 P3384 模板 樹鏈剖分

題目描述 戳這裡 題解 其實樹剖的重點就在於輕重鏈,這篇文章寫的很好 然而我線段樹寫得全是問題,改了半天2333 如下 include include include using namespace std const int maxn 100005 int n,m,root,tt,tot,lnk ...