線段樹yy(線段樹維護括號序列 LCA)

2021-09-26 04:59:30 字數 2505 閱讀 3805

沒有題目鏈結

一顆有 n 個節點的樹,q 組詢問,支援兩種操作:1.單點修改 2.路徑求和。(1 <= n, q <= 1e5)

題解:那麼可以建立一顆有根樹,每次更新時為兩個單點更新(加一次減一次),每次查詢時則是查詢 根的左括號到 x 點的左括號之和 + 根的左括號到 y 點的左括號之和 - 2 * 根的左括號到 x 與 y 的 lca 的左括號之和 + x 與 y 的 lca 的權值。

對拍結果 100% 的**:

#include using namespace std;

typedef long long ll;

typedef unsigned long long ull;

#define int ll

#define pi acos(-1.0)

#define inf 0x3f3f3f3f3f3f3f3f

#define p pair#define fastio ios::sync_with_stdio(false), cin.tie(0)

const int mod = 998244353;

const int m = 1000000 + 10;

const int n = 100000 + 10;

int n, q;

int val[n];

vectorg[n];

int dfn[n<<1], cnt;

int dep[n], gfa[40][n];

int segtr[n<<3], add[n], sub[n];

void dfs(int now, int f)

dfn[++cnt] = -val[now];

sub[now] = cnt;

}void build(int l, int r, int rt)

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

build(l, mid, rt << 1);

build(mid + 1, r, rt << 1 | 1);

segtr[rt] = segtr[rt << 1] + segtr[rt << 1 | 1];

}void update(int pos, int c, int l, int r, int rt)

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

if(pos <= mid) update(pos, c, l, mid, rt << 1);

else update(pos, c, mid + 1, r, rt << 1 | 1);

segtr[rt] = segtr[rt << 1] + segtr[rt << 1 | 1];

}int query(int l, int r, int l, int r, int rt)

int lca(int u, int v)

if(u == v) return u;

for(int k = 31; k >= 0; k --)

}return gfa[0][u];

}signed main()

dep[1] = 1;

dfs(1, -1);

build(1, cnt, 1);

for(int k = 0; k + 1 < 32; k ++)

}cin >> q;

for(int i = 1, x, y; i <= q; i ++) else

}return 0;}/*

rejoicing in hope, patient in tribulation.

*/

隨機生成資料程式:(資料量都是1e5)

#include using namespace std;

int n, m, q, a[10010];

paire[1000005]; // 無向圖,連通,不含重邊、自環

map< pair, bool > h;

int random(int n)

signed main()

for (int i = 1; i < n; i++)

cout << n << endl;

for(int i = 1; i <= n; i ++) cout << a[i] << " ";

cout << endl;

for(int i = 1; i <= n - 1; i ++)

cout << q << endl;

for(int i = 1; i <= q; i ++)

else

cout << x << " " << y << endl;

}return 0;

}

判題程式:

#include using namespace std;

int main()

else }}

線段樹 維護序列

老師交給小可可乙個維護數列的任務,現在小可可希望你來幫他完成。有長為 n 的數列,不妨設為 a1,a2,an。有如下三種操作形式 把數列中的一段數全部乘乙個值 把數列中的一段數全部加乙個值 詢問數列中的一段數的和,由於答案可能很大,你只需輸出這個數模 p 的值。輸入格式 第一行兩個整數 n 和 p ...

線段樹 I 維護序列

老師交給小可可乙個維護數列的任務,現在小可可希望你來幫他完成。有長為 nn 的數列,不妨設為 a1,a2,ana1,a2,an。有如下三種操作形式 input 第一行兩個整數 nn 和 pp 第二行含有 nn 個非負整數,從左到右依次為 a1,a2,ana1,a2,an 第三行有乙個整數 mm,表示...

模板 維護序列2(線段樹)

取模取掛可真是令人質壁分離。兩兩乘積和可以直接用兩個區間的區間和相乘再加上兩個區間各自的乘積和得到,而相鄰乘積和直接兩段相加再加上左區間右端點與右區間左端點乘積就好了。注意 mod mod includeusing namespace std typedef long long ll const l...