TC SRM568,奇妙的題目

2021-08-10 21:34:10 字數 1321 閱讀 3812

這道題一開始的想法是瞎貪心一波,建張圖出來,然後跑帶花樹,看看是否有完美匹配。

描述一下如何建圖,首先貪心,如果連線乙個已知點對的半圓方向能向上就向上,否則向下。

再引入乙個概念,對於乙個未確定點

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...