一些經典的容斥問題

2022-08-03 13:39:20 字數 3481 閱讀 1284

求三角形的個數比較簡單。首先全集是$\binom$,然後考慮補集,補集就是三點共線的點對。所以我們可以列舉每乙個點,然後為了避免算重,我們接下來只考慮標號比當前點小的點。接著就進行極角排序,這樣就可以統計出當前點所在的所有直線以及直線上的點的個數。設某直線上有$m$個點,那麼答案就減去$\binom$即可。注意處理重點的情況。

求銳角三角形的個數也比較簡單,只不過補集除了三點共線之外,還會有鈍角三角形和直角三角形。然而我們還是可以考慮列舉每乙個點$u$,只不過這裡不需要只考慮標號比當前點小的點了,因為接下來的演算法不會算重。然後也還是極角排序,然後按照極角序列舉另乙個點$v$,這樣就構成了一條線段$u-v$。然後過點$u$作線段$u-v$的垂線,那麼在垂線另一邊或者正好在垂線上的點都和$u,v$構成非銳角三角形或直線,統計這樣的點的個數即可,利用單調性可以做到$o(n)$求解。然後每個非銳角三角形或直線會被算兩次,所以最後再除以2就行了。

至於題目的話,就寫個正解寫個暴力拍一拍吧。反正你們這麼強,分分鐘就可以寫完。

首先考慮全集,就是$m\times (m-1)^$。意思就是第乙個點任選顏色,後面的點任選和上個點不同的顏色。聽起來很靠譜,但是最後乙個就可能和第乙個變成一樣的顏色。所以我們要減去補集,就是最後乙個和第乙個顏色相同的情況的種數,即$m\times (m-1)^$。然後發現又減多了,把倒數第二個和倒數第乙個顏色相同的情況也給減掉了,實際上這是不能減的,所以我們要加回來,即加上$m\times (m-1)^$。就這樣一直反覆,直到最後沒有後續狀態了為止。所以有:

$$ans=m\times(m-1)^-m\times(m-1)^+m\times(m-1)^-m\times(m-1)^+...+m\times(-1)^$$

最後用等比公式求和即可簡化計算。

再給乙個類似的題吧。 f題

首先全集就是$\binom$,要走$n+m-2$步,其中有$n-1$步是往下,所以總方案數就是$\binom$。做這類題目的關鍵因素之一就是能夠很快的算出或者預處理出乙個子矩陣的全集。然後我們考慮補集,我們考慮只經過了乙個障礙點的路徑,假設該障礙點是$(u,v)$,那麼所有經過該障礙點的路徑條數即為$s(u,v)\times s(n-u+1,m-v+1)$,其中$s(x,y)$表示從$(1,1)$走到$(x,y)$的放案數,即$\binom$。然後將其減去。但是我們再來考慮那些經過了兩個障礙點的路徑,這些路徑被減去了兩次,所以我們要加回來。然後又要減去經過了三個障礙的,加上經過了四個障礙的......所以我們可以考慮給障礙點之間連邊。$(u,v)$給$(p,q)$連邊當且僅當$u\le p$且$v\le q$且$u\neq p,v\neq q$。但是在這樣的圖中鏈是很多的,所以我們可以考慮動態規劃。設$dp[i][j]$表示從$(1,1)$開始,以$j$結尾的包含了$i$個障礙點的路徑條數,轉移就列舉$j$的每乙個後繼$u$,令$dp[i+1][u]+=dp[i][j]\times s(x_u-x_j+1,y_u-y_j+1)$,然後$dp[i][j]$對答案的貢獻就是$dp[i][j]\times s(n-x_j+1,m-y_j+1)\times (-1)^i$,累加貢獻即可。複雜度是$o(calc_s\times k^3)$的,其中$calc_s$是計算$s$的時間複雜度。

給乙個類似的題:

我把我的**貼上來吧,僅供參考。

1 #include 2 #include 3 #include 4 #include 5 #include 6

using

namespace

std;

7 typedef long

long

ll;8

#define n 100 + 5

9#define mod 110119

1011

intcase, r, ans, fac[mod], inv[mod], ord[n], tmp[n][n], w[n][n];

12bool

ok[n], inq[n];

13ll n, m, x[n], y[n], _x[n], _y[n];

14 vector to[n], vec[n];

1516 inline int inc(int a, int

b)17

2021 inline bool cmp(int u, int

v)22

2526 inline int power(int u, int

v)27

34return

res;35}

3637 inline void

prepare()

3846

47 inline int c(int x, int

y)48

5253 inline int

com(ll x, ll y)

5460

61 inline int

get(ll u, ll v)

6269

70 inline int get_1(int u, int

v)71

7576 inline void

handle()

7785

for (int k = 1; k <= r; k ++)

86101

}102

}103

}104

105int

main()

106118

for (int i = 0; i <= r + 1; i ++)

119for (int j = 0; j <= r + 1; j ++)

120 tmp[i][j] = -1, w[i][j] = 0

;121 sort(ord + 1, ord + r + 1

, cmp);

122for (int i = 1; i <= r; i ++)

123 _x[i] = x[ord[i]], _y[i] =y[ord[i]];

124for (int i = 1; i <= r; i ++)

125129

if (n == 1 && m == 1

)130

134if (!ok)

135139 x[r + 1] = n, y[r + 1] = m, ok[r + 1] = 1

;140

for (int i = 0; i <= r + 1; i ++)

141to[i].clear(), vec[i].clear();

142for (int i = 1; i < r; i ++)

143for (int j = i + 1; j <= r; j ++)

144if (x[j] > x[i] && y[j] > y[i] &&ok[j])

145to[i].push_back(j);

146handle();

147 printf("

case #%d: %d\n

", ++case, ans);

148}

149return0;

150 }

hdoj 5794

有關容斥原理的一些東西

設有若干個物品以及 k 種屬性,每個物品都有若干種屬性。設有函式 f s 表示至少擁有屬性集合 s 的物品個數 參考乙個很簡單的 k 3 的情況 每種顏色的圓的物品集合都擁有同乙個屬性,圓外面是沒有屬性的物品,設全集 u 為所有屬性的集合。一般來說,我們要求三個圓面積的交。形式化的說,我們要求至少擁...

關於錯排的容斥定理的一些心得

賀卡問題 同室四人各寫一張賀年卡,先集中起來,然後每人從中拿一張別人送的賀年卡,則四張不同的賀年卡不同的分配方式有。現在考慮用排除法求出1 2 3 4這四個正整數的錯排的種數,從中摸索出規律.對於四個正整數1 2 3 4,這四個數的全排列數為4 有乙個數不錯排的情況應排除,由於1排在第1位的有3 種...

一些經典的排列問題

組合數學的研究物件中,根據有無順序,一般分為排列問題和組合問題。排列與組合的根本區別在於前者與元素的順序有關,後者與元素的順序無關。在排列與組合的問題中,經常會出現計數問題,解決計數問題的思路一般有以下三種 1.只取要的。即把各種符合條件的情形列舉出來,再利用加法原理求和 2.先全部取,再減去不要的...