日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

容斥原理

發(fā)布時(shí)間:2024/8/1 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 容斥原理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

容斥原理——這種思想很重要

由于前幾天沒有善待自己的身體,導(dǎo)致我昨天不得不去醫(yī)院檢查一下身體(︶︶),結(jié)果醫(yī)生說我是精神上的壓力造成的,這個(gè)就讓我很懵逼了,我覺得是我之前飲食不規(guī)律加上熬夜,然后又劇烈運(yùn)動(dòng)造成的(︶︶),算了,今天吃了藥,感覺好了一點(diǎn),又來給小伙伴們分享一些小算法了,不過在這還是想提醒大家,身體真的很重要哦(_)∠※,好的,下面我們切入正題,來看看這個(gè)困擾了我一天的容斥定理是個(gè)什么鬼

容斥原理的定義:
上中學(xué)學(xué)集合的時(shí)候我們都知道這樣兩個(gè)公式:
**A∪B = A+B – A∩B (∩:重合的部分) **
A∪B∪C = A+B+C – A∩B – B∩C – C∩A +A∩B∩C

這兩個(gè)公式幫助我們解決了很多以我們當(dāng)時(shí)的邏輯能力很難想開的問題(下面是一些小的例子):

例1: 一次期末考試,某班有15人數(shù)學(xué)得滿分,有12人語文得滿分,并且有4人語、數(shù)都是滿分,那么這個(gè)班至少有一門得滿分的同學(xué)有多少人?
分析:
依題意,被計(jì)數(shù)的事物有語、數(shù)得滿分兩類,“數(shù)學(xué)得滿分”稱為“A類元素”,“語文得滿分”稱為“B類元素”,“語、數(shù)都是滿分”稱為“既是A類又是B類的元素”,“至少有一門得滿分的同學(xué)”稱為“A類和B類元素個(gè)數(shù)”的總和。
答案:
15+12-4=23

**例2:**電視臺向100人調(diào)查前一天收看電視的情況,有62人看過2頻道,34人看過8頻道,其中11人兩個(gè)頻道都看過。兩個(gè)頻道都沒看過的有多少人?
100-(62+34-11)=15

例3:(小學(xué)奧數(shù)題)某校六⑴班有學(xué)生45人,每人在暑假里都參加體育訓(xùn)練隊(duì),其中參加足球隊(duì)的有25人,參加排球隊(duì)的有22人,參加游泳隊(duì)的有24人,足球、排球都參加的有12人,足球、游泳都參加的有9人,排球、游泳都參加的有8人,問:三項(xiàng)都參加的有多少人?
分析:
參加足球隊(duì)的人數(shù)25人為A類元素,參加排球隊(duì)人數(shù)22人為B類元素,參加游泳隊(duì)的人數(shù)24人為C類元素,既是A類又是B類的為足球排球都參加的12人,既是B類又C類的為足球游泳都參加的9人,既是C類又是A類的為排球游泳都參加的8人,三項(xiàng)都參加的是A類B類C類的總和設(shè)為X。注意:這個(gè)題說的每人都參加了體育訓(xùn)練隊(duì),所以這個(gè)班的總?cè)藬?shù)即為A類B類和C類的總和。
答案:
25+22+24-12-9-8+X=45 ,解得X=3

例4:(高中題)在1到1000的自然數(shù)中,能被3或5整除的數(shù)共有多少個(gè)?不能被3或5整除的數(shù)共有多少個(gè)?
分析:
顯然,這是一個(gè)重復(fù)計(jì)數(shù)問題(當(dāng)然,如果不怕麻煩你可以分別去數(shù)3的倍數(shù),5的倍數(shù))。我們可以把“能被3或5整除的數(shù)”分別看成A類元素和B類元素,能“同時(shí)被3或5整除的數(shù)(15的倍數(shù))”就是被重復(fù)計(jì)算的數(shù),即“既是A類又是B類的元素”。求的是“A類或B類元素個(gè)數(shù)”。我們還不能直接計(jì)算,必須先求出所需條件。1000÷3=333……1,能被3整除的數(shù)有333個(gè)(想一想,這是為什么?)同理,可以求出其他的條件。

例5:(高中題)分母是1001的最簡分?jǐn)?shù)一共有多少個(gè)?
分析:這一題實(shí)際上就是找分子中不能與1001進(jìn)行約分的數(shù)。由于1001=7×11×13,所以就是找不能被7,11,13整除的數(shù)。
解答:
1~1001中,有7的倍數(shù)1001/7 = 143 (個(gè));有11的倍數(shù)1001/11 = 91 (個(gè)),有13的倍數(shù)1001/13 = 77 (個(gè));有711=77;77是11的倍數(shù)1001/77 = 13 (個(gè)),有713=91;91是13的倍數(shù);1001/91 = 11 (個(gè)),有11*13=143;143是13的倍數(shù)1001/143 = 7 (個(gè)).有1001的倍數(shù)1個(gè)。
由容斥原理知:在1~1001中,能被7或11或13整除的數(shù)有(143+91+77)-(13+11+7)+1=281(個(gè)),從而不能被7、11或13整除的數(shù)有1001-281=720(個(gè)).也就是說,分母為1001的最簡分?jǐn)?shù)有720個(gè)。

上面的兩個(gè)公式其實(shí)是容斥原理在要求所并集合很少情況下的公式,那如果所并集合特別多呢?下面讓我們慢慢揭開容斥原理這層神秘的面紗吧(⊙o⊙)

容斥原理是一種重要的組合數(shù)學(xué)方法,可以讓你求解任意大小的集合,或者計(jì)算復(fù)合事件的概率。

容斥原理可以描述如下:
要計(jì)算幾個(gè)集合并集的大小,我們要先將所有單個(gè)集合的大小計(jì)算出來,然后減去所有兩個(gè)集合相交的部分,再加回所有三個(gè)集合相交的部分,再減去所有四個(gè)集合相交的部分,依此類推,一直計(jì)算到所有集合相交的部分。
上述描述的公式形式可以表示如下:

它可以寫得更簡潔一些,我們將B作為所有Ai的集合,那么容斥原理就變成了:

這個(gè)公式是由 **De Moivre (Abraham de Moivre)**提出的。
我們來用維恩圖來表示集合A、B和C:

那么最后的面積就是集合A、B、C各自面積之和減去A與B相交的面積,A與C相交的面積,B與C相交的面積,再加上A、B、C相交的面積。由此,我們也可以解決n個(gè)集合求并的問題。

容斥原理的證明:

下面是一些簡單的應(yīng)用例子:
**例1:**一個(gè)簡單的排列問題
由0到9的數(shù)字組成排列,要求第一個(gè)數(shù)大于1,最后一個(gè)數(shù)小于8,一共有多少種排列?
我們可以來計(jì)算它的逆問題,即第一個(gè)元素<=1或者最后一個(gè)元素>=8的情況。
我們設(shè)第一個(gè)元素<=1時(shí)有X組排列,最后一個(gè)元素>=8時(shí)有Y組排列。那么通過容斥原理來解決就能夠用到公式:
A∪B = A+B – A∩B (∩:重合的部分)
經(jīng)過簡單的組合運(yùn)算,我們得到了結(jié)果:

然后被總的排列數(shù)10!減,就是最終的答案了。

**例2:**方程整數(shù)解問題

下面我就以代碼的形式給大家展示一下容斥原理在編程中如何使用的:

注意:在容斥原理中排列組合公式會(huì)被經(jīng)常遇到:

例:求指定區(qū)間內(nèi)與n互素的數(shù)的個(gè)數(shù)

Problem description:

Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N. Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than 1 or, equivalently, if their greatest common divisor is 1. The number 1 is relatively prime to every integer.

Input

The first line on input contains T (0 < T <= 100) the number of test cases, each of the next T lines contains three integers A, B, N where (1 <= A <= B <= 10 15) and (1 <=N <= 10 9).

Output

For each test case, print the number of integers between A and B inclusive which are relatively prime to N. Follow the output format below.

Sample Input

2
1 10 2
3 15 5

Sample Output

Case #1: 5
Case #2: 10

Hint
In the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.

這道題的意思是指我先給你一個(gè)數(shù)N,然后再給你一個(gè)范圍[A,B],然后讓你找出該區(qū)間內(nèi)所有和N互質(zhì)的數(shù)的個(gè)數(shù)(不知道什么叫互質(zhì)的同學(xué),請點(diǎn)擊該鏈接:http://blog.csdn.net/sand8o8time/article/details/76781541),要求先輸入多少組測試數(shù)據(jù),然后再分別輸入A,B,N,輸出要求是輸出成Case #1: (結(jié)果)的形式**(?? . ??)**

舉個(gè)例子 [1,10] 區(qū)間中與 6 互素的個(gè)數(shù),應(yīng)該是 10?(10/2+10/3) 但是這樣多減去了 他們的最小公倍數(shù) 6 的情況,所以在加上 10/6 也就是:
10?(10/2+10/3?10/6)=3
這就用到了容斥原理,知道了這個(gè),題目也就可以做了,先進(jìn)行素因子分解,然后二進(jìn)制枚舉子集,再進(jìn)行容斥原理(奇加偶減)。

看了我之前的博客,或者有一定的數(shù)論基礎(chǔ)的大佬可能會(huì)發(fā)現(xiàn)如果所給的范圍是1~n,那么就是歐拉函數(shù)了`()′,好的廢話不多說,下面我們來看AC代碼:

#include<iostream> using namespace std; typedef long long LL; const int Max = 1000010; int primeFactor[Max]; int primeNum; LL A,B,N; void ergFac(int n) {primeNum = 0;for(int i = 2;i*i<=n;i++){//只需要算到前根號n項(xiàng)即可,之前在歐拉函數(shù)中已經(jīng)解釋過,具體的請參看我的歐拉函數(shù)代碼中的注釋 if(n%i==0){ //這里的找質(zhì)因子的處理方法不是很好,之前的歐拉函數(shù)模板中有更好的處理方法 primeFactor[primeNum++]=i; while(n%i==0) //這個(gè)循環(huán)的作用是把n中所有的質(zhì)因子都除掉,比如12就有2個(gè)2的質(zhì)因子和1個(gè)3質(zhì)因子 n/=i;}}if(n>1) primeFactor[primeNum++]=n; //因?yàn)閕是循環(huán)到根號n(起初的n),所以最后n(最后的n,n是一直在變化的)的值很有可能大于根號n(起初的n),并且為質(zhì)數(shù) } LL solve(LL y) {LL ans=0; //這個(gè)ans是用來記錄1~y中所有和n不互質(zhì)的數(shù)得的個(gè)數(shù) for(LL i=1;i<(1<<primeNum);i++){ // i<(1<<primeNum)這個(gè)是不是感覺很神奇?我也想了好一會(huì)才想明白,這個(gè)相當(dāng)于i<2^k,這個(gè)源于組合數(shù)學(xué)中的排列組合(在),Ck,1 Ck,2````Ck,k ,沒有Ck,0的原因是有k個(gè)因子,至少要選一個(gè)作為因子吧 LL ant=0; //ant是用來記錄使用了多少個(gè)質(zhì)因子 LL q=1; //q是用來記錄使用的所有的質(zhì)因子的乘積 for (LL j=0;j<primeNum;j++){ //j是用來做位運(yùn)算的,第一層循環(huán)中我們發(fā)現(xiàn) i<(1<<primeNum) if(i&(1<<j)){ //看代碼末尾ant++;q*=primeFactor[j];}}if(ant&1) ans+=y/q; //這個(gè)是容斥原理中的容斥原理(奇加偶減) else ans-=y/q; }return ans; } int main() {int t,flag=0;cin>>t; while(t--){cin>>A>>B>>N;ergFac(N);cout<<"Case #"<<++flag<<": "<<B-A+1-solve(B)+solve(A-1)<<endl;} return 0; } //這個(gè)地方讀者可以拿幾組數(shù)據(jù)自己來調(diào)一調(diào),理解的更快一點(diǎn),這個(gè)是用來判斷 ,主要是用來判斷 從primeNum中選幾個(gè)質(zhì)因子相乘得q ,位運(yùn)算很容易給大家整暈哈,但是用起來很是靈活 ,比如題目上的第二組測試數(shù)據(jù),primeNum = 1,為2,那么i=1時(shí)能夠判斷i<(1<<primeNum),也就是說只有從1個(gè)數(shù)中取一個(gè)的情況,如果primeNum = 2,那么就有從2個(gè)中取1個(gè),和2個(gè)中取2個(gè)的情況,一共有3中情況 (2個(gè)中取1個(gè)d的是兩種)

總結(jié)

以上是生活随笔為你收集整理的容斥原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。