傳送門:鐵人兩項
簡述一下題目:
給出乙個(不一定聯通)的圖,求有多少個三元組(s,c,f)滿足s,c,f都是圖中的點,且存在一條從s到c的路徑和一條從c到f的路徑,使得兩條路徑沒有公共點(除c以外)。
這個題當時剛接觸到圓方樹,我的想法跟正解十分接近使我非常興奮。
這個題我們想一下如果n2的話我們要怎麼做:
列舉兩個圓點s,f。路徑上所有的點雙中的點都可以作為c。如何方便地統計呢?首先我們建出圓方樹,把圓點權值設為-1(因為正常計算有重複路徑,這樣直接免去容斥減的過程),方點權值設為點雙的大小,則s到f的路徑上的點(包括s,f)的權值和,也就是c的個數。這是n方的。
如果列舉中間點,則很容易求出樹上有多少個圓圓路徑經過這個點,通過這個點的子樹大小直接o(1)進行計算即可,這樣我們只用把所有的點列舉一遍即可,這樣是o(n)的。
**先咕咕咕
**成功的沒有咕咕咕:
#define b cout << "breakpoint" << endl;#define o(x) cout << #x << " " << x << endl;
#define o_(x) cout << #x << " " << x << " ";
#define msz(x) cout << "sizeof " << #x << " " << sizeof(x)/1024/1024 << " mb" << endl;
#include#include#include#include#include#include#include#define ll long long
#define inf 1000000009
#define n 1000005
using namespace std;
inline int read()
while(ch >= '0' && ch <= '9')
return s * w;
}ll ans;
int vis[n];
int n,m,top,res,tot,s;
int dfn[n],low[n],stk[n],val[n],sz[n];
struct graph
inline void init(int u,int v)
} eold,enew;
inline void cmin(int &x,int y)
void tarjan(int u)
val[res] = cnt;
sz[u] += sz[res];
enew.init(res,u);
}} else
} return ;
}void dfs(int u,int fa)
ans += 2ll * x * sz[v] * val[u];
x += sz[v];
dfs(v,u);
} return ;
}void pre()
return ;
}void solve()
} printf("%lld",ans);
return ;
}int main()
2018APIO 進京趕考
先見識了一下ctsc的操作。漲了見識。打鐵匠x1 見識了個全英文的ppt,各種講課其實真的講的很好,只是邏輯性太強反而讓完全不會的同學有些尷尬。linux真的令人窒息。guide用不起就算了,控制台除錯。報錯直接密密麻麻打5頁螢幕看都看不懂。編譯都編譯不起我還玩個啥?我就聽懂了凱老師的講課,彈幕令人...
遊記 APIO2018遊記
update 雞排真好吃,明年有機會再來北京van明天就要去北京浪了,於是在模擬apio2015前嘗試去做了hash,很愉快地wa了,就開始了模擬apio2015的比賽。a題亂搞,c題亂搞,b題結果暴力都沒寫出來。感覺這為後面暴力沒搞出來暴力打好了堅實的基礎 hdhd過金牌線。總體還是很愉快的,每個...
APIO2018 鐵人兩項
題意 在乙個無向圖裡面選三個點 s c f 需要能夠從 s 出發,經過 c 到達 f 點,中間不能提前經過 f 且需要是乙個簡單路徑 solution 簡單路徑當然就是園方樹了,想想怎麼統計答案 yy一下可以發現,有一條路徑 s f 中間能選的點就是路徑上的圓點和 因為在乙個點雙連通分量裡面,一定有...