SDOI2013 泉(搜尋 hash 容斥)

2022-03-17 00:08:01 字數 1189 閱讀 2755

給定\(n\)個時間,每個時間有六個權值,求恰好有\(k\)個權值對應相等的時間對的對數

由於權值數量很少,可以列舉哪些權值相等,然後將每個時間的對應權值拿出來hash一遍,就可以得到有多少對時間的這些權值相同

但是這樣顯然會算重複,比如有四個權值相同的時間對它的三個權值也會相同,於是可以開始容斥了

設\(f_i\)表示至少有\(i\)個權值對應相等的時間對的對數,即上面求出來的陣列;設\(g_i\)表示恰好有\(i\)個權值對應相等的時間對的對數,即答案

看起來應該是\(f_i=\sigma ,(i\leq j\leq 6)\),但是其實\(f_i\)中會有不止乙個\(g_j\),如\(j=5,i=3\)時,\(f_3\)會在\(g_5\)裡面任選三個值加起來,所以會加\(c(5,3)\)次\(g_5\)

即\(f_i=\sigma,(i\leq j\leq 6)\)

由上面可知,\(g\)的式子應該是\(g_i=f_i-\sigma ,(i

#include#define n 1000005

#define re register

using namespace std;

typedef long long ll;

typedef unsigned long long ull;

const ull base = 1000000007;

int n,k,a[n][7],st[7],top;

ll f[8],g[8],c[10][10];

ull has[n];

template void read(t &x)

void deal()

sort(has+1,has+n+1);

ll len=0;

for(re int i=1;i<=n;++i)

else ++len;

} f[top]+=(len-1)*len/2;

}int main()

read(n);read(k);

for(re int i=1;i<=n;++i)

for(re int j=1;j<=6;++j)

read(a[i][j]);

for(re int i=0;i<64;++i)

for(re int i=6;i>=k;--i)

cout《其實看懂了正解就知道\(g_i=f_i-f_\)不對,因為會出現多次,但這也是筆者這種萌新容易混的地方

SDOI2013 刺客信條

故事發生在1486 年的義大利,ezio 原本只是乙個文藝復興時期的貴族,後來因為家族成員受到聖殿騎士的殺害,決心成為一名刺客。最終,憑藉著他的努力和出眾的天賦,成為了傑出的刺客大師,他不僅是個身手敏捷的武林高手,飛簷走壁擅長各種暗殺術。刺客組織在他的帶領下,為被剝削的平民聲張正義,趕跑了原本統治義...

SDOI2013 保護出題人

出題人銘銘認為給sdoi2012 出題太可怕了,因為總要被罵,於是他又給sdoi2013 出題了。參加sdoi2012 的小朋友們釋放出大量的殭屍,企圖攻擊銘銘的家。而你作為sdoi2013的參賽者,你需要保護出題人銘銘。殭屍從唯一一條筆直道路接近,你們需要在銘銘的房門前放置植物攻擊殭屍,避免殭屍碰...

SDOI2013 保護出題人

點此看題 感覺這道題網上講解不是特別清楚,我來補一發詳細講解吧,因為作者也是花了好久才搞懂。首先把題目所求轉化成形式化表達 其中s ss是生命值a aa的字首和 i 1nmax j 1is i s j 1 x i i j d sum n max i frac i 1 n j 1maxi x i i ...