50-1(19.10.23)(樹的性質):
https://codeforces.com/contest/516/problem/D
https://codeforces.com/contest/516/submission/63242051
大意:
給一棵樹,定義\(d[x]=max(dis(x,y))\)。
求一個聯通塊\(S\),使得\(max(d[x∈S])-min(d[y∈S])<=l\),求\(max(|S|)\)。
\(d[x]\)肯定是\(x\)到直徑兩個端點的最大值。
然后發現可以直接lct維護聯通塊大小。
發現性質,若以d最小的為根建樹,\(d[fa[x]]<=d[x]\)。
那么就是掃描線,對於x,可以用樹狀數組直接統計子樹里\([d[y]<=d[x]+l]\),因為連續。
上網發現還可以直接用並查集維護聯通塊大小,刪掉時直接減1,並查集不用變,還是因為連續。
50-3(19.10.24)(計數+分治):
https://atcoder.jp/contests/agc023/tasks/agc023_e
https://atcoder.jp/contests/agc023/submissions/8106222
大意:
求滿足p[i]<=a[i],p是一個排列,p的逆序對數和。
考慮求p的方案數。
從大到小給每個數選擇位置,這樣的話就可以確定這個數可以放的位置數。
設\(cnt[i]=\sum [a[j]>=i]\),\(Ans=\prod cnt[i]-(n-i)\)
要考慮逆序對數的話,枚舉兩個\(i,j(i<j)\),假設\(a[i]<=a[j]\)
當\(p[j]>a[i]\)時,不會產生逆序對數,將\(a[j]\)調整至\(a[i]\),發現恰好有一半的排列就是\(p[i]>p[j]\)的。
若\(a[i]>=a[j]\),考慮用總數-順序對數,順序對數和上面一樣,把\(a[i]\)調整至\(a[j]\)
若調整\(a[i]<=a[j]\),則\(cnt[x]--,x∈(a[i],a[j]]\),對合法排列的影響可以預處理\({cnt[i]-n+i-1\over cnt[i]-n+i}\)的區間積來實現目的。
這樣得到了\(O(n^2)\)的做法。
用線段樹分治來統計答案就是\(O(n~log~n)\)的。
50-2(19.10.24)(概率+積分):
https://atcoder.jp/contests/agc032/tasks/agc032_f
https://atcoder.jp/contests/agc032/submissions/8109887
大意:
一個圓被隨機\(n\)條直徑分割,設\(s\)為一個扇形的面積,求\(min(|s-1/3|)\)。
第一步需要一個不可能想到的轉換考慮把一條線定位0°,然后划分成三個區域,0-120°,120-240°,240°-360°
這個區域里的划分看作三種顏色紅綠藍,然后全部\(mod~120°\)搞到\(0-120°\)里,發現問題變為\(0-120°\)里,隨機\(n-1\)條划分,顏色也隨機,求顏色不同的划分的最近距離,注意0°視作有一條紅色的,120°視作有一條藍色的。
\(n-1\)條弧把1/3的區域划分成了\(n\)段。
設\(E(i)\)表示長度為1的線段分成\(n\)段第\(i\)長段的期望長度。
通過推理可以得到:
$Ans=
\(Ans=\sum_{i=1}^n 3^{i-1}*(E(i)-E(i-1))*{1\over 3}\)。
即一條線段兩個點同色的概率是\({1 \over 3}\),要使\(E(i)-E(i-1)\)被統計到,則\(i\)以前的線段都要同色,所以是\(3^{i-1}\),長度上限是\({1\over3}\),還要乘\({1\over 3}\)。
問題在於求\(E(i)\)。
先求\(E(1)\),設\(P(i)\)表示長度為1的線段分成\(n\)段最短線段長度\(>=i\)的概率。
\(E(1)=\int_{x=0}^{1/n} P(x) ~dx\)
\(P(x)=(1-nx)^{n-1}\),下面將解釋這個東西:
考慮把線段分為\(a(a->∞)\)段,在其中隨機選\(n-1\)個點就分成了\(n\)段,方案數是\(a^{n-1}\)。
現在要求每一段線段的長度都\(>=x\),可以理解成少了\(nx*a\)個點,還剩\(a-nx*a\)個點,方案數是\((a-anx)^{n-1}\)。
則概率就是\((a-anx)^{n-1}/a^{n-1}=(1-nx)^{n-1}\)。
\(\int_{x=0}^{1/n} (1-nx)^{n-1}~dx\)
\(=\int_{x=0}^{1/n} x^{n-1} ~ dx\)
\(=1/n^2\)
所以\(E(1)={1 \over n^2}\)
然后推\(E(2)-E(1)\)。
這個就比較簡單了,\(E(2)\)相當於還剩下\(1-E(1)*n\)的長度,分給\(n-1\)段,最短期望長度。
那么就是\(E(2)=(1-{E(1)*n})/(n-1)^2=n*(n-1)\)。
通過數歸可以得到:\(E(k)-E(k-1)={1\over n*(n-k+1)}\)
那么這題的答案就是:\(Ans=\sum_{i=1}^n {1 \over 3^in(n-k+1)}\)。
49-1(19.10.26)(決策+貪心):
https://codeforces.com/contest/506/problem/C
https://codeforces.com/contest/506/submission/63412933
https://codeforces.com/contest/506/submission/63421859
大意:
有n個竹子,第i個竹子長度為h[i],每天的結束會長高a[i]
現在有m天,每一天可以做k次操作,每次操作可以選擇一個竹子砍掉p,即高度h[i]=max(h[i]-p,0)
你需要最小化m天結束后最高的竹子的高度
n<=100000,m<=5000,k<=10
首先二分答案x。
solution1:
然后發現直接順着搞無法決策每次機會給誰。
於是逆着搞,問題等價於,一開始每根竹子的高度是x,每次先降低a[i],操作可以拔高p,要求每根竹子任何時候高度非負,且最后的高度>=h[i]。
那么這個問題十分簡單,主要是沒了max(0,h-p)這種不好考慮得東西,先把所有操作留着,當一個竹子要h<0時,就給他加p,最后再填到h[i],看操作夠不夠用就行了。
要用\(priority\)_\(queue\),\(set\)被卡常。
solution2:
每根竹子至少要\(c[i]=\lceil {x + a[i]* m - h[i] \over p}\rceil\),事實也不會要更多次。
假設要多了一次,不如不做前面的那次不滿p的,效果是一樣的。
然后設\(d[i][j]\)表示第i根竹子的第j次操作至少要在\(d[i][j]\)天后。
\(d[i][j]\)怎么求是個好問題。
先思考\(c[i]\)刀要滿足什么才能合法,就是它們的效果和\(>=x+a[i]*m-h[i]\)
也就是\(>=(c[i]-1)*p+(x+a[i]*m-h[i])~mod~p\)
則對於任意前\(j\)刀,砍的時候要滿足:
\(h[i]+(d[i][j]-1)*a[i]>=(j-1)*p+(x-h[i])~mod~p\)
搞一下\(d[i][j]\)就出來了。
接着掃一遍,看看夠不夠用就好了。
1-2(19.10.26)(性質+線段樹):
https://codeforces.com/contest/674/problem/G
https://codeforces.com/contest/674/submission/63429991
大意:
給出n個數,每次可以對一個區間進行整體賦值,或者詢問一個區間頻率\(>=p\%(20<=p<=100)\)的數。
在編程之美上看過這樣一個問題:
有n個單詞,其中有k個單詞頻率\(>={1 \over k +1}\),其它的都小於\({1\over k +1}\),要求利用\(O(k)\)的空間找出這k個單詞。
考慮k=1的時候,只需要記錄一個單詞和一個計數器,如果新的單詞和記錄的一樣,計數器+1,否則-1,當計數器=0時,記錄的單詞變為新的單詞。
\(k>1\),類似的,就記k個不同的單詞和計數器,加入一個新的,有相同的就把計數器+1,否則計數器全部-1,有計數器=0的就替換。
證明就是把上面的看做每次找k+1個不同的單詞刪掉,最后剩下的一定是那k個單詞。
對於這道題,可以看做做\(k=\lfloor100/p\rfloor\),用線段樹維護,\(O(k^2)\)暴力合並兩個表即可。
時間復雜度:\(O(n~log~n~*k^2)\)
49-2(19.10.31)(勢能分析,線段樹)
https://codeforces.com/contest/679/problem/E
https://codeforces.com/contest/679/submission/63884902
大意:
有一個序列,每次可以區間賦值,或者區間加,如果區間加完后這個區間有42的次冪,那就繼續求,還有詢問一個的值。
42的次冪在int范圍里的只有6個。
我們對每一個數設一個\(dis[i]\)表示\(a[i]\)到下一個42的冪的距離。
區間加法相當於dis區間減法,當減到<=0時,就順便判一下並改一下,如果沒有2操作的話,因為一個數最多被搞6次,復雜度就是:
\(O(n~log~n*6)\)。
考慮有了2操作,如果一個區間實際值一樣,且dis<=0,那么一起修改,容易證明,復雜度還是:
\(O(n~log~n*6)\)。
48-1(19.10.31)(tarjan縮強聯通分量)
https://codeforces.com/contest/555/problem/E
https://codeforces.com/contest/555/submission/63894938
太水了不講了。
49-3(19.10.31)(轉換模型+貪心+樹形dp)
https://atcoder.jp/contests/arc098/tasks/arc098_d
https://atcoder.jp/contests/arc098/submissions/8223881
大意:
給出一個聯通無向圖,走到一個點的時候至少要有\(a[i]\)的金幣,可以花下\(b[i]\)的金幣買下這個點,求最少要多少金幣才能把所有點買一遍。
我只能想到先選\(a[i]-b[i]\)大的比較優,但是這只能用於完全圖的情況,然后就不會了。
事實上可以這么轉換問題,就變得明了。
設\(c[i]=max(0,a[i]-b[i])\),要保證只要在這個點上,\(金幣數>=c[i]\)。
這個問題,不難想到把\(c[i]\)最大的提出來,越早買它越好。
但是它的鄰節點可以分成多個聯通塊,如果一開始就買了,可能就不能走到了其它地方了。
所以一定留在最后一個聯通塊進去前買。
記\(sumb[i]\)表示i為根的來聯通塊的\(\sum b\)
記\(g[i]\)表示i為根的聯通塊所需的金幣數\(-sumb[i]\)。
考慮\(g[x]\)怎么轉移,直接枚舉最后走到的聯通塊y,因為\(c[x]\)是子聯通塊里最大的,所以一定能不用額外的金幣通過其它子樹,對於這個聯通塊所需的額外金幣是\(max(g[y],c[y]-sumb[y])\),取所有y的最小值即可。
48-2(19.10.31)(辣雞結論題):
https://atcoder.jp/contests/agc032/tasks/agc032_e
https://atcoder.jp/contests/agc032/submissions/8226893
大意:
把2n個數分成n對,使得\(max((a[i]+a[j]) ~mod ~m)\)最小化。
大膽猜想可以找到一個分界點,使得左邊第一個和最后一個,第二個和倒數第二個……右邊也是如此
這樣會最優,證明可以看題解那6個圖,然后用不等式做做發現就是對的。
題解:https://img.atcoder.jp/agc032/editorial.pdf
於是二分這個分界點就好了。
48-3(19.10.31)(博弈+最優化決策):
https://atcoder.jp/contests/agc032
https://atcoder.jp/contests/agc023/submissions/8229211
大意:
數軸上\(n\)個點,第i個點是\(x[i]\),人數為\(p[i]\)。
一開始所有人在車上,車在\(S\)上,每次進行投票,往正或者往負走,到達一個\(x[i]\)時,\(x[i]\)上的\(p[i]\)人會下來。
每個人禿頂聰明,會希望自己在車上的時間最小,輸出最后下的人的時間。
*想題兩小時,做題五分鍾——論atcoder做題感受。
很不自然地考慮\(1\)和\(n\)兩個地方的人的決策。
若\(p[1]>=p[n]\),即使\(n\)上面的人把車往右邊拉,走到了\(x[n-1]\),由於\(p[1]>=p[n]\),車還是往回走。
也就是\(n\)一定在\(1\)的后面,\(T(n)=T(1)+x[n]-x[1]\),所以\(n\)上面的人不如讓\(T(1)\)最小,也就是跟着\(1\)決策。
\(p[1]+=p[n]\),現在變成了\([1-n-1]\),求\(T(1)\)的子問題,遞歸求解。
\(p[1]<p[n]\)的情況同理。
直到最后只剩一邊的人,那么就不用決策了,直接走。
43-1(19.10.31)(分段矩陣乘法):
https://codeforces.com/contest/575/problem/A
https://codeforces.com/contest/575/submission/63930223
一眼題不說了,mdzz要判k=0和k=1。
47-1(19.11.1)(矩陣乘法+倍增):
https://codeforces.com/contest/576/problem/D
https://codeforces.com/contest/576/submission/63987413
設\(T(i)\)表示i時間,從1出發,能到那些點。
\(F(i)\)表示,\(i\)以前的邊所形成的轉移矩陣。
\(T(n+1)=T(n)*F(n)\)
而這些邊按時間排序,之間的\(F\)是一樣的。
用倍增去試即可,注意維護的是\(F(n)^{1..x}\)的或和。
47-2(19.11.1)(結論+二分圖網絡流):
https://atcoder.jp/contests/agc029/tasks/agc029_f
https://atcoder.jp/contests/agc029/submissions/8241674
什么LJ猜結論題。
我只能把題解復述一遍了。
對於一棵樹,當我們去掉一個點后,剩下的點和邊必須有完美匹配,可以理解為以這個點作根,每個點和它到父親的邊匹配。
對於每個點都要滿足這個,這顯然是有解必要條件。
其實這還是充分條件。
考慮分別以u、v作根,把兩個完美匹配圖取並集,你會發現一定有一條從u到v的路徑,因為u、v的度數=1,而其他點的度數都=2。
這也說明假設以\(u\)為根,跑完美匹配,如有\(x,y\in s[i],s[i]~choose~x\),\(x->y 連邊\)。
那么從u開始dfs,若滿足之前的必要條件,一定能夠走到其它的所有點(相當於沿着路徑更改匹配的選擇)。
這恰好也是一組答案。
10-1(19.11.2)(點分治二分樹上凸函數):
https://codeforces.com/contest/566/problem/C
https://codeforces.com/contest/566/submission/64055933
考慮一條鏈的情況,考慮選的位置是x,則代價=\(\sum abs(p[i]-x)^{1.5}*w[i]\)。
這是若干凸函數的和,還是一個凸函數。
那么鏈上直接二分即可。
樹上用點分治二分即可,每次看往哪個子樹走優。
36-1(19.11.2)(庫默爾定理+數位dp):
https://codeforces.com/contest/582/problem/D
https://codeforces.com/contest/582/submission/64057294
很久以前做過的。
https://blog.csdn.net/Cold_Chair/article/details/77488682
9-2(19.11.2)(set):
https://codeforces.com/contest/674/problem/D
https://codeforces.com/contest/674/submission/64057984
37-2(19.11.4)(動態規划):
https://codeforces.com/contest/704/problem/B
https://codeforces.com/contest/704/submission/64202127
不錯的一道拆絕對值dp題。
x是遞增的,那么我們不需要考慮具體是誰和誰匹配,只需要知道方向即可。
從左往右做,左邊就可以剩下兩類點,一類是缺一條來自右邊的入邊,一類是缺向左的出邊,一個點可以同時是第一類和第二類。
設\(f[i][j][k]\)表示前i個點,一類點j個,二類點k個,最小值。
然而在不考慮起點和終點時,\(j=k\),因為有入必有出。
經過起點后,第二類比第一類多一個,經過終點后,第一類比第二類多一個。
這樣就少了一維。
dp時可以記當前第二類比第一類多了h=0、-1、1個點。
轉移時注意除了一開始和最后,第一類和第二類點至少要有一個,不然就不聯通了。
4-3(19.11.4)(構造):
https://atcoder.jp/contests/agc030/tasks/agc030_c
https://atcoder.jp/contests/agc030/submissions/8291382
發現豎着橫着都不行,於是就斜着。
使\(n=k,color[i][j]=(i+j)\%n+1\)。
你得到了和橫着豎着一樣的解法。
發現這個東西,每一條斜線可以塞兩個顏色……也不會錯……
2-3(19.11.4)(動態規划):
https://atcoder.jp/contests/agc030/tasks/agc030_d
https://atcoder.jp/contests/agc030/submissions/8292283
考慮設\(f[i][j]\)表示若干操作后,\(a[i]>a[j]\)的方案數。
若當前是交換\(x,y\)。
對f的影響就是,要么就是×2,即\(i、j\)與\(x、y\)無關,要么就是很簡單的轉移。
所以維護個整體×2標記,每次只修改相關的,最后統計一下就好了。
13-2(19.11.5)(二元關系網絡流):
https://atcoder.jp/contests/agc038/tasks/agc038_f
https://atcoder.jp/contests/agc038/submissions/8299844
考慮每個環只有轉一下和不轉,我們可以對i討論一下貢獻。
\(1.p[i]=q[i]=i\)
不管怎樣都不會有貢獻。
\(2.p[i]=q[i],p[i]≠i\)
只有兩個都不轉或兩個都轉才沒有貢獻。
\(3.p[i]≠q[i],p[i]=i\)。
只有q轉了才有貢獻。
\(4.p[i]≠q[i],q[i]=i\)
只有p轉了才有貢獻。
\(5.p[i]≠q[i],p[i]≠i且q[i]≠i\)
只有都不轉才沒有貢獻。
由第2條可以得到兩邊的方向是相反的。
不妨設\(p\)屬於\(S\)即選了,\(q\)屬於\(T\)即選了。
連邊的話比較顯然,不寫了。
4-2(19.11.5)(概率+生成函數|min-max容斥+dp):
https://atcoder.jp/contests/agc038/tasks/agc038_e
https://atcoder.jp/contests/agc038/submissions/8303241
設\(P(i)\)表示i還沒有結束的概率。
\(Ans=\sum_{i>=0}P(i)\)
直接算\(P(i)\)並不好算。
考慮設\(Q(i)\)表示第i步已經結束的概率。
\(P(i)=1-Q(i)\)
\(Q(i)=\sum_{d[j]>=b[j]且\sum d[j]=i}{i! \over d[j]!}*\prod({a[j]\over \sum a})^{d[j]}\)
寫成EGF:
\(Q(x)=\prod (e^{{a[j]\over \sum a}x}-\sum_{k=0}^{b[j]-1}({a[j]\over \sum a})^k/k!*x^k\)
\(P(x)=e^x-Q(x)\)
暴力展開求出\(P(x)\)。
考慮最后\(P\)的形式是:
\(\sum c[i][j]*e^{{i\over \sum a}x}*x^j\)
忽略\(c[i][j]\),相當於求\(e^{tx}*x^j\)每一項系數和。
\(=\sum_{i>=0}t^i*x^j/i!*(i+j)!\)
這個是EGF,所以乘上\((i+j)!\)。
\(=j!\sum_{i>=0}t^i*C_{i+j}^j\)
\(=j!*({1\over 1 - t})^{j+1}\)
還可以min-max容斥+dp,只要有意識的靠,再推推式子就能出來,這里不講了。
31-1(19.11.6)(掃描線):
https://codeforces.com/contest/538/problem/H
https://codeforces.com/contest/538/submission/64347902
這個題除了特別長以外就真的只是特別長了。
先對每個聯通塊進行單獨考慮。
不是二分圖直接無解。
是二分圖的話,對二分圖的兩邊分別求區間交。
現在問題就是看每一個二分圖的兩邊分別分到那邊。
假設一個二分圖的兩個邊的區間交分別為\([l1,r1][l2,r2](l1<=l2)\)
一共有三種情況:
\(l2,r2<=r1\)
\(l2<=r1,r2>r1\)
\(l2>r1\)
對這三種情況分別看\(n1\)屬於每一個子區間時,\(n2\)能屬於哪個區間。
然后掃一遍,用個堆來維護即可。
最后還要還原答案,想打出題人。
29-1(19.11.6)(2-SAT):
https://codeforces.com/contest/568/problem/C
https://codeforces.com/contest/568/submission/64362913
比較顯然由字典序去填每一位。
問題相當於有一些為已經確定,問是否有解。
每個點拆位選'V'還是選'C',對一開始的邊,正反都連一下。
已經確定的點,可以直接dfs,或者連一條邊繼續判。
注意要判只有'V'或者'C'的情況。
22-2(19.11.6)(幾何+簡單線性規划):
https://codeforces.com/contest/685/problem/C
https://codeforces.com/contest/685/submission/64371840
考慮二維的時候,我們把曼哈頓變成\((x+y,x-y)\),這樣就變成了矩形。
同樣的,三維我們把它變成四維的:
\(a=x+y+z\)
\(b=x-y-z\)
\(c=-x+y-z\)
\(d=x+y-z\)
二分答案ans后,求四維空間的交。
當然並不是有交就有答案。
若有\(x,y,z\)滿足\(a,b,c\),它不一定滿足\(d\)。
所以要限制一下\(d\),事實上\(d=a+b+c\),專門湊好的。
那么這里做一個簡單的線性規划可以解出\(a,b,c\)。
注意\((x,y,z)\)要是整數,所以反解后得是整數。
\(x=(a+b)/2\)
\(y=(a+c)/2\)
\(z=(b+c)/2\)
可以得出\((a,b,c)\)的奇偶性相同即可。
解出最優答案的\((a,b,c)\)后就好了。
不知道為什么WA on 6,可能是解\((a,b,c)\)時出了一點小問題,正負波動個2就能過了。
30-2(19.11.7)(dp):
https://codeforces.com/contest/704/problem/C
https://codeforces.com/contest/704/submission/64453278
每個點只出現兩次,所以形成的圖的每個聯通子圖要不是是環要不是鏈。
直接dp,要判一堆\(k=1\)帶來的獵奇情況。
6-3(19.11.7)(mst):
https://atcoder.jp/contests/arc093/tasks/arc093_c
https://atcoder.jp/contests/arc093/submissions/8324595
先做出個Mst。
設mst的邊權和為sum。
若\(sum>X\),顯然\(ans=0\)。
若\(sum=X\),設能在mst上的邊有ca個,不在有cb個。
考慮這ca個只要不全部同色就行了。
\(Ans=(2^{ca}-2)*2^{cb}\)。
若\(sum<X\),設替換mst上的最大邊后\(sum>X\)的有\(cb\)個,\(sum=X\)的有ca個。
顯然這ca個至少有一個和\(sum<X\)的異色。
所以\(Ans=2*(2^{ca}-1)*2^{cb}\)。
10-2(19.11.8)(SAM+dp):
https://codeforces.com/contest/700/problem/E
https://codeforces.com/contest/700/submission/64496361
考慮把這個出現兩次卡的緊一些。
比如說一定有一次是后綴,這樣答案並不會變。
但是因為變成了后綴,所以可以在SAM上dp。
考慮SAM上一個節點x代表着長度在一個區間的串,設\(f[x]\)表示x代表的最長串的答案。
\(f[x]\)可以由\(f[fa[x]]\)轉移過來,至於為什么只考慮最長串之間的dp,可以看:
https://blog.csdn.net/litble/article/details/81179442
的證明。
判斷\(f[x]\)能不能由\(f[fa[x]]\)轉移過來可以預處理\(right\)集的線段樹。
注意對每個x要多記\(pos[x]\),含義為:
\(pos[x]=y|y是x的祖先且f[x]=f[y]且min(dep[y])\)
每次實際轉移不是\(x\)和\(fa[x]\),而是\(x\)和\(pos[fa[x]]\)。
13-1(19.11.8)(構造+歐拉回路):
https://codeforces.com/contest/528/problem/C
https://codeforces.com/contest/528/submission/64499842
胡亂構造題,自己造出來也不知道對不對。
首先度數是奇數的點肯定要補成偶數的嘛。
然后考慮對每個聯通塊,每個點都是偶數的度數,可以拉一條歐拉回路。
如果歐拉回路的長度是偶數,那么只要正-反-正-反…就可以滿足題目條件了。
所以如果長度是奇數,隨便在一個點那里加一個自環。
19-1(19.11.8)(kruskal重構樹+線段樹):
https://codeforces.com/contest/571/problem/D
https://codeforces.com/contest/571/submission/64509298
寫完后看了別人的做法感覺自己弱爆了。
當時一看這題,把類似Kruskal重構樹的東西建出來,這樣一個時間內的聯通的點就在一個子樹里了。
然后通過線段樹來打標記求出每個點最近被刪的時間。
再通過線段樹區間加求和來搞定一個點在一個時間以前的答案。
由於就是要做兩遍幾乎一樣的東西,所以代碼達到了200行,雖然寫起來很快。
23-1(19.11.8)(2-sat構造解):
https://codeforces.com/contest/587/problem/D
https://codeforces.com/contest/587/submission/64526348
考慮每個邊拆成選和不選。
同一顏色的邊在同一點可以得到限制。
在同一點的邊可以得到不能同時選的限制,這里新建一些前綴后綴的虛點來搞。
然后二分答案,邊權>ans的不能選,跑2-sat看有沒有解。
最后再隨便給出一組解,這好像是我第一次寫構造解。
可以看這篇博客,有許多證明:
https://blog.csdn.net/litble/article/details/80404751