連環病原體 題解

2022-05-20 07:23:30 字數 1310 閱讀 9871

題目鏈結

題意:一張 $ n $ 點 $ m $ 邊無向圖,每條邊有編號。若乙個區間內的邊能連成乙個環,則稱這個區間為好區間。求每條邊分別在多少個好區間內。

演算法一:

首先想到乙個暴力。列舉區間的左端點,右端點,用並查集判斷是否有環,得分 $ 60 $ 分。

演算法二:

顯然的優化1:設 $ [l, r] $ 表示從 $ l $ 到 $ r $ 的區間滿足條件且從 $ l $ 到 $ r - 1 $ 的區間不滿足條件。 $ l $ 遞增,顯然 $ r $ 不降。

顯然的優化2:對於統計答案,記錄首項和公差,最後跑一邊字首和。

對於優化1,我們需要乙個可以支援加邊和刪邊的並查集, $ lct $ 即可。

得分 $ 90 $ ~ $ 100 $ 分( $ findroot $ 時將結果 $ splay $ 試試?)。

#include#define lc ch[u][0]

#define rc ch[u][1]

using namespace std;

const int n=400010;

typedef long long ll;

int m,a[n],b[n];

int fa[n],ch[n][2],sta[n];

bool lz[n],flag;

ll ans[n],dl[n];

inline bool nroot(int u)

void pushdown(int u)

inline void pushup(int u)

void rotate(int u)

void splay(int u)

}void access(int u)

void makeroot(int u)

int findroot(int u)

void split(int x,int y)

void lnk(int x,int y)

void cut(int x,int y)

int main()

lnk(a[r],b[r]);

} if(!flag) break;

ans[l]=m-r+1,--dl[r+1],--r,cut(a[l],b[l]);

} ll sum=0;

for(int i=1;i<=m;i++) sum+=dl[i],ans[i]=ans[i-1]+ans[i]+sum;

for(int i=1;i<=m;i++) printf("%lld ",ans[i]);

return 0;

}

題解 洛谷 P4230 連環病原體

用雙指標掃瞄來找環,加入 r 位置的邊後,若形成了環,就刪去 l 位置的邊,直到環斷掉,加邊刪邊和判定連通性用 lct 維護即可。考慮如何計算環的貢獻,對於區間 l,r 若其形成了環,則區間 l,r 1 l,r 2 dots l,m 都形成了環。得最終的貢獻為區間 l,r 都加上 m r 1 區間 ...

Luogu4230 連體病原體

題面戳我 很好想 很好寫的一道題,然而比賽中我還是沒有切掉qaq。lct列舉左端點 i 向右移動右端點指標 j 找到第乙個成環的位置。此時 i,j i,j 1 i,m 都是合法答案。可見就是在區間 i,j 上區間加 m j 1 再在 j 1,m 上加上乙個等差數列 m j,m j 1.1 等差數列直...

資料結構與演算法實驗題7 2 連環計

問題描述 赤壁之戰前夕,龐統向周瑜獻連環計,瑜設計使蔣幹邀龐統到曹營。操與統同觀營寨,又共論兵法。統對答如流使操敬服。統乘機提出 大江中風浪不息使北兵易生疾病。可將大 小船配搭,首尾用鐵環連鎖,鋪闊板以便人馬行走。操聞之大喜,派人連夜打造連環大釘,鎖住船隻。每打造一單位長度的鐵索要花費一單位的錢,曹...