[shoi2015]零件組裝機
同機房大佬想性質想了很久,我從樹的思想搞很快搞出來了
言歸正傳,這道題目從樹的思路想是比較簡單的,關鍵是建樹。
現在講講建樹:對於一條邊,預設是從編號大的連向編號小的有向邊。
那麼,設x
xx連向的編號最大的點為y
yy,那麼x,y
x,yx,
y是什麼關係?
我們規定乙個聯通塊的根為這個聯通塊編號最小的點(不難發現聯通塊的編號是連續的),那麼x,y
x,yx,
y的關係其實就是以x
xx為根的聯通塊與[y,
x−1]
[y,x-1]
[y,x−1
]的聯通塊合併。
這樣,我們就只需要根據x,y
x,yx,
y建出一棵樹,從下往上合併,每次合併檢驗一下即可。
需要注意的是:如果存在重邊和自環直接無解。
當然還有乙個性質:合法圖的邊的是在o(n
)o(n)
o(n)
級別的。(同機房大佬找到的)
時間複雜度:o((
n+m)
logm)
o((n+m)\log)
o((n+m
)logm)
用桶排加記憶體池以及其餘細節便可以優化到o(n
+m
)o(n+m)
o(n+m)
。
#include
#include
#include
#include
#define n 110000
using
namespace std;
set<
int> ****[n]
;int cnt,now;
//合法邊的數量
int fa[n]
,siz[n]
;int id[n]
;inline
bool
cmp(
int x,
int y)
inline
bool
check
(int l1,
int r1,
int l2,
int r2)
//檢驗吧[l2,r2]合併到[l1,r1]是否合法
return0;
}int n,m;
intmain()
set<
int>
::iterator ****=****[x]
.find
(y);
if(****==****[x]
.end()
)//重邊無解
else bk=1;
}for
(int i=
0;i)id[i]
=i; siz[0]
=1;for
(int i=
1;i) set<
int>
::iterator x=****[i]
.end()
; x--
;fa[i]
=*x;}if
(bk==1)
for(
int i=n-
1;i>=
1;i--
)siz[fa[i]]+
=siz[i]
;sort
(id,id+n,cmp)
;for
(int i=
0;i1;i++)}
if(bk==
1|| now!=cnt)
printf
("yes\n");
}return0;
}
SHOI2015 超能粒子炮 改
設 f n k sum kc n i pmod 那麼根據盧卡斯定理我們知道 f n k sum kc times c c 0 times sum c i c 1 times sum c i c times sum c i c times sum c i sum c i times c 0 c 1 c...
SHOI2015 自動刷題機
我也想要乙個!顯然能夠看出來單調性 當n越大,能ac的題越少,反之越少。所以。很明顯的二分答案對吧。唯一一點不太一樣的是,它要求可能的最大值,和可能的最小值。那我們就寫兩個check,先求出來最大值,如果算出來的ac題數大於等於k,我們就選擇右區間。然後再0和最大值的區間中再次二分 減小帶的log的...
SHOI2015 超能粒子炮 改
求 sum 2333 n,k leq 10 如果直接套盧卡斯還是比較容易想到分塊求解的 由 c n i c times c 可知,i p 相同的組合數另一部分分別是 i p,i p 1,i p 2.這部分可以搓到一起 令 s n k sum 具體來說,將這部分相同的部分放到一起,剩下的地方直接計算 ...