loj上只掛了兩個無重的題,本來心想水一下,結果被sdoi2011染色那題卡了一發。儘管這題之前做過,但實現很不優美。今天wa的第一發一開始測樣例就掛了,強行除錯半天交上去一分沒有。後來仔細想了想怎樣寫比較清楚(儘管看起來好像有點冗餘),寫好以後一路順風一發就過。從這裡也有點感悟吧。
#include #define int long long
using namespace std;
const int n = 1000005;
int n, m, q, t1, t2, t3, t4;
namespace seg
void build(int p, int l, int r, int *src) else
}void modify(int p, int l, int r, int pos, int val) else else
pushup(p);
}}int querya(int p, int l, int r, int ql, int qr)
if (l >= ql && r <= qr) else
}int queryb(int p, int l, int r, int ql, int qr)
if (l >= ql && r <= qr) else
}} // namespace seg
namespace tree
}void dfs2(int p)
for (int i = 0; i < g[p].size(); i++)
}void presolve()
void modify(int p, int val)
int querya(int p, int q)
if (dep[p] < dep[q])
swap(p, q);
return max(ret, seg::querya(1, 1, n, dfn[q], dfn[p]));
}int queryb(int p, int q)
if (dep[p] < dep[q])
swap(p, q);
return ret + seg::queryb(1, 1, n, dfn[q], dfn[p]);
}} // namespace tree
int src[n], tmp[n];
signed main()
tree::presolve();
for (int i = 1; i <= n; i++)
for (int i = 1; i <= n; i++)
seg::build(1, 1, n, src);
cin >> q;
for (int i = 1; i <= q; i++)
if (op[1] == 'm')
if (op[1] == 's')
}}
這題的思路很常規,無非就是線段樹每個節點除了維護答案多維護左邊和右邊的顏色,然後由於這個答案可以被快速合併,暴力一下就可以了。
線段樹的部分畢竟都是按順序的所以很容易。但樹鏈剖分查詢的時候由於順序翻轉之類的問題,開個結構體以後事情變得清楚了很多。
類似的問題還有很多,比如維護最大欄位和,加等差數列求和等等,把結點物件稍微封裝一下其實就會很容易。當然自己碼力太弱才是真原因啊~~
#include using namespace std;
const int n = 1000005;
int n, m, t1, t2, t3, t4, src[n], tmp[n];
namespace seg
void pushdown(int p)
void build(int p, int l, int r, int *src) else
}void modify(int p, int l, int r, int ql, int qr, int val) else
}int query(int p, int l, int r, int ql, int qr, int &rl, int &rr) else
}int query(int ql, int qr, int &rl, int &rr)
}void dfs2(int p)
for (int i = 0; i < g[p].size(); i++)
}void presolve()
struct result
};result merge(result a, result b)
int query(int p, int q)
if (dep[p] < dep[q])
swap(p, q), inv ^= 1;
result tmp;
tmp.get(dfn[q], dfn[p]);
ret[inv] = merge(tmp, ret[inv]);
swap(ret[0].cl, ret[0].cr);
result ans = merge(ret[0], ret[1]);
return ans.ans;
}void modify(int p, int q, int v)
if (dep[p] < dep[q])
swap(p, q);
seg::modify(1, 1, n, dfn[q], dfn[p], v);
}} // namespace tree
int main()
tree::presolve();
for (int i = 1; i <= n; i++) src[tree::dfn[i]] = tmp[i];
seg::build(1, 1, n, src);
for (int i = 1; i <= m; i++) else
}return 0;
}
一本通學習筆記 最短路徑
最短路徑常用演算法有dijkstra和spfa。spfa支援負數權重,但容易被毒瘤資料卡。想讓spfa跑快點可以加入乙個小優化 用deque代替queue,然後在push的時候分類,如果比當前front的dis要小就push front,否則push back。最短路計數和次短路問題仿照普通dp處理...
樹鏈剖分學習筆記
寫 又犯了很sb的錯誤,線段樹寫錯了。好像每次都會把r l 1寫成l r 1,然後就只有20分。寫的比較醜,壓了壓之後190行。基本上是我打過的最長的乙個模板了 然後簡單介紹一下樹剖吧。樹鏈剖分,就是把樹剖分成鏈,然後用資料結構來維護這些鏈,使得詢問 修改的複雜度達到o logn o l ogn 不...
樹鏈剖分學習筆記
樹鏈剖分 mod estc oder modestcoder modest code r如果你是重兒子,你就在重路徑上。如果你是輕兒子,暴力沿著祖先向上爬最多log nlogn logn 次就可以遇到重路徑。或者到根 而樹上操作基本就是找祖先 也許有人喜歡我的碼風 include include d...