用雙指標掃瞄來找環,加入 \(r\) 位置的邊後,若形成了環,就刪去 \(l\) 位置的邊,直到環斷掉,加邊刪邊和判定連通性用 \(lct\) 維護即可。
考慮如何計算環的貢獻,對於區間 \([l,r]\),若其形成了環,則區間 \([l,r+1],[l,r+2] \dots [l,m]\) 都形成了環。得最終的貢獻為區間 \([l,r]\) 都加上 \(m-r+1\),區間 \([r+1,m]\) 加上乙個首項為 \(m-r\),公差為 \(-1\) 的等差數列。用線段樹維護差分數列即可。
#include#define maxn 200010
#define maxm 800010
#define ls (cur<<1)
#define rs (cur<<1|1)
#define mid ((l+r)>>1)
using namespace std;
typedef long long ll;
templateinline void read(t &x)
while(isdigit(c))
if(flag)x=-x;
}int m,root=1,pos=1;
int fa[maxn],ch[maxn][2],rev[maxn];
ll sum[maxm],add[maxm],ans[maxn];
struct edge
e[maxn];
void pushadd(int cur,int l,int r,ll v)
void pushdown(int cur,int l,int r)
void modify(int l,int r,int l,int r,ll v,int cur)
pushdown(cur,l,r);
if(l<=mid) modify(l,r,l,mid,v,ls);
if(r>mid) modify(l,r,mid+1,r,v,rs);
sum[cur]=sum[ls]+sum[rs];
}void dfs(int l,int r,int cur)
pushdown(cur,l,r);
dfs(l,mid,ls),dfs(mid+1,r,rs);
}bool check(int x)
bool notroot(int x)
void pushrev(int x)
void spread(int x)
void rotate(int x)
void all(int x)
void splay(int x)
void access(int x)
void makeroot(int x)
void split(int x,int y)
int findroot(int x)
void link(int x,int y)
void cut(int x,int y)
int main()
link(x,y);
}dfs(1,m,root);
for(int i=1;i<=m;++i)
ans[i]+=ans[i-1],printf("%lld ",ans[i]);
return 0;
}
《題解》洛谷P3385 模板 負環
題目鏈結 判斷一張圖中是否存在關於頂點1的負環 可以用spfa跑一遍,存在負環的情況就是點進隊大於n次 因為在存在負環的情況下,spfa會越跑越小,跑進死迴圈 在最差的情況下,存在的負環長度是 n 1個頂點 這麼長 顯然這是n個點長度,但不是環 這就是乙個環,n 1個點的長度 所以 很明了了,只需將...
洛谷P5022 旅行 題解 去環 搜尋
這道題目一開始看的時候沒有思路,但是看到資料範圍裡面有乙個 m n 1 或 m n 一下子有了思路。當 m n 1 時,這就是一棵樹,以1為根節點進行搜尋,每次優先訪問編號小的點即可。當 m n 時,可知只有乙個環,找到環中對應的所有邊,然後遍歷每一條環中的邊,假設刪除它,然後就變成了一棵樹。時間複...
洛谷P1008 三連擊題解合集
題目傳送門 本題為提交答案題,您可以寫程式或手算在本機上算出答案後,直接提交答案文字,也可提交答案生成程式。將1,2,9共9個數分成3組,分別組成3個三位數,且使這3個三位數構成1 2 3的比例,試求出所有滿足條件的3個三位數。暴力九重迴圈 include include int main syst...