SHOI2014 三叉神經樹 LCT

2022-05-07 08:21:06 字數 1506 閱讀 2203

題面:

loj#2187

解析:顯然修改一次需要修改一條到根的鏈, 維護鏈當然就想到用lct了

結果就想偏了, 本來想分別維護虛子樹資訊與整棵子樹資訊,結果發現很難維護。然後去自學了一發

我們定義乙個點的點權為它的兒子節點中選$1$的個數

考慮更改乙個點的點權要麼對它上方的鏈中連續的$1$或連續$2$, 因此splay中每個節點分別維護能到的最深的不是$1$的點與不是$2$的點,然後是乙個區間修改和單點修改了,直接在splay中搞就行了

注意更新父親節點時的順序,先用右兒子更新,再用左兒子

**:

#include#include

#include

using

namespace

std;

const

int maxn = 500004, inf = 0x3f3f3f3f

;inline

intread()

int n, m, f[maxn<<1], a[maxn<<1

], root, ans;

bool

vis[maxn];

struct

lcttr[maxn];

inthead[maxn], tot;

struct

edgee[maxn];

void addedge(int x, inty);

head[x] =tot;

}void dfs(int

x) tr[x].nd1 = (tr[x].val != 1?x: inf);

tr[x].nd2 = (tr[x].val != 2?x: inf);

}void update(int

x)void spread(int

x)

if(rs)

tr[x].add = 0

;

}}bool isroot(int

x)void rotate(int

x)void pushdown(int

x)void splay(intx)}

void access(intx)}

intmain()

else

f[x-n] =i;}}

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

a[i] = read(), tr[f[i]].val +=a[i];

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

if(!vis[i])

ans = (tr[root].val > 1

); m =read();

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

update(now);

}else

a[x] ^= 1

; printf(

"%d\n

", ans);

}return0;

}

view code

SHOI2014 三叉神經樹

給你一顆由 n 個非葉子結點和 2n 1 個葉子結點構成的三叉樹,每個結點兒子個數為 0 3 每個葉子結點有乙個輸出 0 或 1 每個非葉子結點的輸出為自己的葉子結點中較多的那一種狀態。有 q 次修改操作,每次修改乙個葉子結點的輸出,求每次修改後根結點的輸出。n leq 5 times 10 5,q...

SHOI2014 三叉神經樹

題目描述 計算神經學作為新興的交叉學科近些年來一直是學術界的熱點。一種叫做shoi 的神經組織因為其和近日發現的化合物 shtsc 的密切聯絡引起了人們的極大關注。shoi 組織由若干個 shoi 細胞構成,shoi 細胞之間形成嚴密的樹形結構。每個 shoi 細胞都有且只有乙個輸出端,被稱為軸突,...

SHOI2014 三叉神經樹 題解

lct 一顆節點數為 3n 1 的樹,編號在 1 dots n 的節點有且僅有三個兒子。其餘點沒有兒子。所有節點值只可能為 0 或 1 編號在 n 1 dots 3n 的節點的值由輸入確定,編號在 1 to n 的節點的值為三個兒子中值數量更多的那種。m 次操作,每次會改變乙個 n 1 dots 3...