聯賽模擬18 聯盟

2022-04-12 05:42:35 字數 1955 閱讀 1545

沒有用\(o(n)\)的做法,是\(o(nlogn)\)的線段樹維護直徑 (o(n)的需要維護的資訊我覺得又多又亂)

將樹的節點按\(dfs\)序建線段樹維護聯通塊的直徑

列舉每一條邊,檢視刪掉它之後,剩餘的兩個聯通塊合併後的直徑 所能取到的 最小的最大值

即 最小的 len=max \) + \(\frac\) +1}

\(l_1和l_2\) 是兩個聯通塊的直徑。

記錄\(len\)的最小值及其個數,以及此時的要刪的邊的編號。

對於找端點,選一條要刪的邊,輸出其端點,然後分別\(dfs\)找到兩個聯通塊直徑的中點輸出即可

code

#include #include #include #include #include using namespace std;

char buf[1<<20],*p1,*p2;

#define l (rt*2)

#define r (rt*2+1)

#define rint register int

#define gc() (p1==p2?(p2=buf+fread(p1=buf,1,1<<20,stdin),p1==p2?eof:*p1++):*p1++)

#define read() ()

const int maxn=3e5+5;

int n;

int cnt;

int time;

int head[maxn];

int dfn[maxn],ref[maxn];

int dep[maxn],fa[maxn],son[maxn],siz[maxn],top[maxn];

int min=0x3f3f3f3f;

int mx[maxn][2];

int jilu[maxn];

int g,max_part;

int no_vis;

struct segt[maxn*4];

struct edgee[maxn*2],ed[maxn];

void aedge(int x,int y)

void dfs1(int x,int prt)

} }ans=(seg);

return ans;

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

seg find(int rt,int l,int r,int x,int y)

void dfs(int x,int prt)

}void find_g(int x,int prt,int dep){

if(!g||max(mx[x][0],dep)dep[y]) swap(x,y);

seg a2;

if(dfn[y]+siz[y]<=time) a2=up(find(1,1,n,1,dfn[y]-1),find(1,1,n,dfn[y]+siz[y],time));

else a2=find(1,1,n,1,dfn[y]-1);

int len2=cal(a2.x,a2.y);

if(len2>min) continue;

seg a1=find(1,1,n,dfn[y],dfn[y]+siz[y]-1);

int len1=cal(a1.x,a1.y);

if(len1>min) continue;

int d=max(max(len1,len2),(len1+1)/2+(len2+1)/2+1);

if(d

聯賽模擬測試18 A 施工未補

非正解二維莫隊碾過 vegetable include include include include include define int long long using namespace std inline int read inline void write register int x ...

聯賽模擬測試34

考場打表 rand 正解可以根據乙個倍數往上翻 如果乙個數b是a的n倍,那麼b可以由a貼上n次得到 開乙個佇列按照每個因數倍增幾次取最小即可 藍書原題 csp考試之前還看來著 然後考場假了 打了暴力滾粗 下來之後一點就透了 等比數列求和 對於唯一一組hack資料 是mod完階乘出0了 特判一次直接往...

聯賽模擬測試33

區間dp g i j 表示從第i位到第j位中間有多少不重複出現的數字 f i j 表示合併i到j能獲得的收益之和 特隊兒在寫的時候 正序遍歷掛成零分 原來是沒有學習經驗 還是要注意遍歷方法 眾所周知,乙個合格的oier不僅要會數奧,物奧,生奧 甚至還要會一點點美術 考試的時候畫了好久 打表拿到了 5...