題目大意:給你內向基環樹森林,一開始每個點都有個人,每秒所有人會沿著出邊走一步,你可以在任意秒取走某個點的人(只能取一次),使得人數最多。現在你要修改盡量少的出邊,使得最後你能取出最多的人,以及假設剛剛的答案是k,對每個t∈[
0,k]
t\in[0,k]
t∈[0,k
]求修改t條邊後,你最多能拿到多少人。n≤1
05
n\le10^5
n≤10
5題解:
第一問顯然是聯通快數或者減1。
考慮第二問,假設現在在算t
tt的答案。
首先未必最後形成自環最優。有這樣一件事情:t-1的答案對應操作集合不一定是t的答案對應操作集合的子集,但是當固定t的時候,一定存在一種最優解,其餘若干連通塊都是斷掉換邊連到某個環上。
那麼列舉最後是否形成自環。
若是,則分一開始是否就有自環,然後按照點數排個序就可以了。
否則,考慮列舉當根的環的環長l,那麼我們發現斷掉某個環的邊並到這個長為l的環的時候,我們對兩個連通塊(後者是斷開邊的樹)分別做l-分層,然後分別求出兩個連通塊出現次數最多的層數出現的次數,然後加起來。
那麼可以對所有連通塊,斷掉所有環邊求貢獻,去最大值就是這個連通塊對l的貢獻,然後取出環長是l的環的連通塊中,答案最大的那個,然後把剩下連通塊中貢獻最大的t個合併上去即可。
最後怎麼求斷掉一條邊求貢獻,這個一開始任意欽定刪掉某條邊算一下,然後依次列舉刪哪條邊,發現受影響的點只有那條邊頂點及其子樹中的點,因此總複雜度是連通塊大小級別的,因此對所有連通塊算貢獻是線性的。
優秀的實現(比如桶排)可以做到n乘以根號n(因為不同的環長最多只有根號n種)。
#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<#define sp <<" "
#define ln <#define clr(a,n) memset(a,0,sizeof(int)*((n)+1))
#define clrv(v) vector().swap(v)
using namespace std;
typedef pair<
int,
int> pii;
typedef set<
int>
::iterator sit;
inline
intinn()
const
int n=
100010
;struct edgese[n<<1]
;int h[n]
,etop,onc[n]
,sz[n]
,p[n]
,vis[n]
,ans[n]
;vector<
int> lst[n]
,dc[n]
;inline
intadd_edge
(int u,
int v)
inline
intgetd
(int x,
int fa,
int dpt,vector<
int>
&dc,
int&sz)
inline bool lszcmp
(const vector<
int>
&v1,
const vector<
int>
&v2)
namespace sort_space
}using sort_space:
:sort;
namespace solve1_space
else
return0;
}}namespace solve2_space
inline
intdel
(int x)
inline
intins
(int x,
int k)
inline
intdel
(int x,
int k)
inline
intgetgx
(vector<
int>
&p,int cl)
int res=ans;
rep(i,
0,m-2)
rep(i,
0,m-1)
return res;
}inline
intsolve
(int cl,
int cnt,
int*ans)
inline
intsolve2
(int cnt,
int*ans)
}namespace getans0_space
int res=0;
rep(i,
0,t-
1) res=
max(res,cnt[i]);
return res;}}
intmain()
sort
(lst+
1,lst+cnt+
1,lszcmp)
;rep
(i,1
,cnt)
reverse
(lst[i]
.begin()
,lst[i]
.end()
);rep(i,
1,cnt)
rep(j,lst[i]
) lst[i]
[j][onc]
=i;clr
(sz,cnt)
;rep
(i,1
,n)if
(onc[i]
)clrv
(dc[i]),
getd
(i,0,0
,dc[i]
,sz[onc[i]])
;int stp=
(lst[1]
.size()
==1?cnt-
1:cnt)
;printf
("%d\n"
,stp)
;clr
(ans,stp)
;rep
(i,1
,cnt) ans[0]
=max
(ans[0]
,getans0_space:
:getans0
(lst[i]))
; solve1_space:
:solve1
(cnt,ans)
,solve2_space:
:solve2
(cnt,ans)
;rep
(i,0
,stp)
printf
("%d "
,ans[i]);
printf
("\n");
}return0;
}
在為時已晚前 阻止物聯網安全威脅和攻擊
物聯網 iot 裝置是最新一波直接連線到ip網路的裝置,這也帶來新的網路安全風險。在過去,網路靜態連線首先預留給有限數量的昂貴的計算機,隨後網路連線開始提供給企業 使用者家中 移動裝置,現在開始連線到大量iot裝置。過去大量資源專門用於連線計算機到靜態網路,但在物聯網時代,這些資源已經減少。而專用於...
英特爾振興移動晶元業務努力為時已晚?
他認為,這可能導致英特爾 非我發明症 not invented here 文化的改變,最終幫助它在新興增長市場上獲得成功。數年前英特爾似乎還有在移動晶元市場上獲取相當高市場份額的野心。英特爾完成了多起收購交易,以獲得進入移動晶元市場所必需的寶貴智財權,並在研發方面投入巨資。人們不能說英特爾沒有努力。...
自然角度論有機體的反脆弱性
最近看了黑天鵝的作者的反脆弱性一書,突然有了個想法,解釋我們的世界。人類具有反脆弱性,什麼是反脆弱性,比如,你打疫苗,打部分病毒,毒量比較小,但是身體產生了抗性。比如,你在工廠天天搬重物的工作,身體很累,但是身體產生了適應性,你的肌肉開始增長。脆弱性,也就是你在溫和的場所,懶散,閒得慌,舒適,無壓力...