題目大意:有一顆有$m$個葉子節點的二叉樹。
對於葉子節點$i$,$x[i]=(a[i]\ xor\ v_)or(b[i]\ xor\ v_)$
對於非葉子節點$i$,$x[i]=x[sonl]\ and\ x[sonr]$。
上文的$or$和$xor$均為邏輯運算子。且v為乙個長度為$n$的布林陣列,需要你自己構造。
下面問:對於每個非葉子節點$i$,問是否存在乙個序列v,使得$x[i]=true$。
資料範圍:$n,m≤2\times 10^$
我們先來考慮下暴力應該怎麼做
我們直接暴力將以$i$為根的子樹內所有葉節點取出,轉換出對應的了邏輯表示式,然後根據2-sat那一套建圖,直接tarjan即可。
這麼搞,資料優秀的話(給你乙個毛毛蟲圖),你就會**
考慮一種不會**的做法:
我們對這棵樹跑一次樹剖,我們根據鏈長依次在鏈上進行二分,查詢出最接近根的,能夠構造出true的點。
然後冷靜分析一波,發現這個複雜度好像是$o(n\log^2\ n)$的,似乎問題不大。
可是問題在於這一題採用$o(n^2)$的做法可以直接艹過此題,我就並沒有去寫高階做法了qwq
1 #include2#define m 500005
3using
namespace
std;45
int n,m,rt=0;6
int p[m]=,q[m]=,a[m]=,b[m]=,in[m]=;
78 vectorg[m];910
void
readdata()
17for(int i=m+1;i2;i++)
23for(int i=1;i2;i++)
24if(in[i]==0)25}
2627
struct edgee[m*2]=; int head[m]=,use=0;28
void add(int x,int y)
29int dfn[m]=,low[m]=,b[m]=,d[m]=,cnt=0,t=0; stacks;
30void dfs(int
x)while(u!=x);41}
42}4344 vectorlist;
45void findpoint(int
x)55
for(int i=0;i)
56findpoint(g[x][i]);57}
5859
bool check(int
x)70
for(int i=0;i)
76for(int i=0;i)
82return1;
83}8485
int ans[m]=;
86bool solve(int x,int
ok)92
93int
main()
2019北京集訓測試賽(十三) 函樹 虛樹
題目大意 給你一顆 n 個節點的樹,定義 d x,y 點 x 到點 y 最短路上經過的邊數。求 sum limits sum limits varphi i times j times d i,j 答案對998244353 取模。我們對這個式子做一些細微的處理,設最終的答案為 ans ans sum...
北京集訓D2T3 tvt
首先需要對兩條路徑求交,對給出的四個點的6個lca進行分類討論。易於發現路徑的交就是這六個lca裡面最深的兩個所形成的鏈。然後即可再分兩種情況進行討論。對於同向的路徑,我們可以求出到達交的起點的時間差,然後與鏈上的最長邊進行比較,如果大於說明可行。對於對向的路徑,如果能在時間差內走到交集上,同時不是...
2016北京集訓測試賽1 奇怪的樹 樹鏈剖分
對於操作1,不論選了哪個點為a,最後反轉顏色的點集都只有兩種型別 顯然啦 暴力解法 對每個操作3,從a向上直到根節點,每到乙個節點記錄 它父親的黑點數減去自己的黑點數 父親節點的編號。另外,還要記錄a子樹內的黑點。這種o n2 的做法肯定會爆,考慮優化。由於這是一棵靜態樹,考慮樹鏈剖分。需要記錄乙個...