題面:
loj#2187
解析:顯然修改一次需要修改一條到根的鏈, 維護鏈當然就想到用lct了
結果就想偏了, 本來想分別維護虛子樹資訊與整棵子樹資訊,結果發現很難維護。然後去自學了一發
我們定義乙個點的點權為它的兒子節點中選$1$的個數
考慮更改乙個點的點權要麼對它上方的鏈中連續的$1$或連續$2$, 因此splay中每個節點分別維護能到的最深的不是$1$的點與不是$2$的點,然後是乙個區間修改和單點修改了,直接在splay中搞就行了
注意更新父親節點時的順序,先用右兒子更新,再用左兒子
**:
#include#includeview code#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;
}
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...