這道題一開始的想法是瞎貪心一波,建張圖出來,然後跑帶花樹,看看是否有完美匹配。
描述一下如何建圖,首先貪心,如果連線乙個已知點對的半圓方向能向上就向上,否則向下。
再引入乙個概念,對於乙個未確定點
p ,定義f(
d,p)
為d方向上覆蓋了這個點的半圓集合。
考慮存在乙個方向dx
使得f(
dx,p
1)等於f(
dx,p
2)的點對(p
1,p2
) 之間連一條邊,跑下帶花樹,我的演算法就結束啦。
下面是正解的開始。 定義g
(b) 為半圓b所包含的點集,可以證明前面的圖存在完美匹配就等價與所有的g(
b)大小都是偶數。
並且,前述的貪心建圖,是不對的,應當列舉。
列舉完了之後,可以通過字首和的思想將問題轉化為二分圖判定,複雜度最壞o(
2n/2
n)。理論上是不能過的,但是tc上8086ms硬給卡過去了,實際上可以用些特技來加速。
下面是蒟蒻的**:
#include
#include
#include
#include
#include
const
int n=115;
class disjointsemicircles
inline
void dif(int x,int y)
inline
void equ(int x,int y)
public:inline
std::string getpossibility(std::vector
labels)
if(!cnt)return
"possible";
//for(i=0;i//for(i=0;ifor(i=0;i<1
for(j=0,w[0]=w[1]=0;jif(~labels[j])else
if(~ll[j])--w[o];
}if(jcontinue;
for(j=0;jif(l[j]!=r[j])else
if(l[j]==r[j]-1)continue;
if(i>>j&1)else
}for(j=0,equ(0,n);j<=n && gfa(j)!=gfa(j+d);++j);
if(j>n)return
/*printf("%d\n",i),*/
"possible";
}return
"impossible";
}};
TC srm518 Nim 動態規劃 FWT
題目大意 求符合以下條件的序列個數 1 長度為k 2 每個元素大小不超過l 3 每個數都是質數 4 所有數異或和為0 k 109,l 50000 答案對109 7取模 解題思路 我們設f i j 表示序列長度為i,異或和為j的方案數,那麼 f i x y f i 1 x f 1 y 可以發現這個式子...
5 第 5 章 迴圈
1.可以用迴圈來驗證輸入。在迴圈前的第一次讀取操作,稱為啟動讀取,如果後續還需要繼續讀取,則語句應該在迴圈中。2.在實際程式設計應用中,不建議在 cout 語句中放置遞增或遞減運算子 因為容易出錯 3.需要計數時使用計數器,需要累計彙總時使用累加器。4.標記符號是乙個特殊值,指示著值列表的結尾。一般...
5X5矩陣調換!
將乙個5x5矩陣中最大的元素放在中心,4個角分別放4個最小的元素,寫一函式實現之!include int main printf n return 0 void change int p temp p 12 p 12 pmax pmax temp temp p p pmin pmin temp pm...