1. 程式人生 > >TrickGCD(容斥原理 & 篩數 & 好題)

TrickGCD(容斥原理 & 篩數 & 好題)

2017多校聯合

很容易想到我們要列舉GCD,然後用每一個數除以它,再連乘,得到公約數含這個數的方案數。然後再用容斥原理減掉多餘的部分。

但是問題就在,如果一個一個算的話,複雜度是min(Ai)* n,達到了1e10的複雜度,肯定不行。

如果我們用篩數的方法來列舉每一個除數,就能很快的算出來(類似素數篩,nlogn)。這個篩法的思路是:我們計算被除數中滿足當前除數的情況下,商為k的數的個數,然後把它們乘起來。

最後用一次容斥原理,算出結果。

程式碼如下:

#include<queue>
#include<cmath>
#include<stack>
#include<cstdio>
#include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; #define INF 0x3f3f3f3f #define CLR(a,b) memset(a,b,sizeof(a)) #define PI acos(-1.0) #define MAX 100000 const LL MOD = 1e9 + 7; LL ant[MAX+5]; //數字出現的次數 LL num[MAX+5
]; //數字的字首和 LL dp[MAX+5]; //記錄每個GCD的方案數 LL QuickMod(LL a,LL b) { LL ans = 1; while (b) { if (b & 1) ans = ans * a % MOD; a = a*a % MOD; b >>= 1; } return ans; } int main() { int T; int Case = 1; int n; int minn; scanf
("%d",&T); while (T--) { minn = INF; scanf ("%d",&n); CLR(ant,0); while (n--) { int t; scanf ("%d",&t); minn = min(minn,t); ant[t]++; //統計每個數的個數 } for (int i = 1 ; i <= MAX ; i++) //求字首和 num[i] = num[i-1] + ant[i]; for (int i = 2 ; i <= MAX ; i++) //列舉除數 { if (i > minn) //記得這個,剛開始就是因為沒有初始化dp才錯的 { dp[i] = 0; continue; } dp[i] = 1; for (int j = 0 ; j <= MAX ; j += i) //求出各段的商的積 { LL a,b; //商,個數 a = j / i; if (j == 0) //直接得出 b = 0; else if (i+j-1 > MAX) //超過上限 b = num[MAX] - num[j-1]; else //利用字首和計算出中間數字的個數 b = num[i+j-1] - num[j-1]; dp[i] = dp[i] * QuickMod(a,b) % MOD; } } LL ans = 0; for (int i = MAX ; i >= 2 ; i--) //利用容斥原理求結果 { for (int j = i+i ; j <= MAX ; j += i) { dp[i] = (dp[i] - dp[j] + MOD) % MOD; } ans = (ans + dp[i]) % MOD; } printf ("Case #%d: %lld\n",Case++,ans); } return 0; }

相關推薦

TrickGCD原理 & &

很容易想到我們要列舉GCD,然後用每一個數除以它,再連乘,得到公約數含這個數的方案數。然後再用容斥原理減掉多餘的部分。 但是問題就在,如果一個一個算的話,複雜度是min(Ai)* n,達到了1e10的複雜度,肯定不行。 如果我們用篩數的方法來

HDU 4135——Co-prime原理&&二進位制列舉

題目連結: 模板 void prime(ll n) { k=0; for(int i=2;i*i<=n;i++) { if(n%i==0) { Prime[k++]=i; while

bzoj4558 [JLoi2016]方原理,計數,Hash

這容斥真是寫的我心態爆炸… 考慮用至少0個壞點的-至少1個壞點的+至少兩個壞點的-至少三個壞點的+至少四個壞點的。 我們發現對於斜著的正方形,可以直接在框住它的大正方形處計數,邊長為i的大正方形內就有i個正方形。 且我們發現每個點出現且僅出現在一個正方形上

BZOJ4559 JLOI2016成績比較原理+組合數學+斯特林

  容斥一發改為計算至少碾壓k人的情況數量,這樣對於每門課就可以分開考慮再相乘了。剩下的問題是給出某人的排名和分數的值域,求方案數。枚舉出現了幾種不同的分數,再列舉被給出的人的分數排第幾,算一個類似斯特林數的東西即可。後一部分與碾壓幾人是無關的,預處理一下,複雜度即為三方。當然和四方跑得也差不多快。   資

#19. 計數原理

cnblogs += void lld ring 輸入輸出 計數 define printf 時間限制:1s 內存限制:256MB 【問題描述】 給出m個數a[1],a[2],…,a[m] 求1~n中有多少數不是a[1],a[2],…,a

HDU 4390 Number Sequence 原理+組合計數

osi freopen ret dsm algo .cn iterator push_back man HDU 4390 題意: 大概就是這樣。不翻譯了:

『ZOJ 3547』The Boss on Mars 原理

ostream idt employee ant mars pri mes because reason 傳送門戳這裏qwq 題目描述 On Mars, there is a huge company called ACM (A huge Company on M

GCD HDU - 1695原理

stdin false print ont 分享 typedef vector swa sed 要求從滿足gcd(x, y) = k的對數,其中x屬於[1, n], y屬於[1, m] gcd(x, y) = k ==>gcd(x/k, y/k) =1 x/k

hdu4153原理求質數

ase class ace ini n) turn sign for http 傳送門 ac代碼: #include<bits/stdc++.h> #define per(i,a,b) for(int i=a;i<=b;i++) usin

【BZOJ1030】文本生成器原理,AC自動機,計數DP

color 容斥原理 求長 sca 計數 sin strlen amp 思路 題意:給出n個字符串,求長為m至少包含n個裏其中一個的串的字符串一共有多少個,字符集為A到Z,答案對10007取模 n<=60,len<=100 思路:將至少一個轉化為所有個數減去沒有

Newcoder 39 E.集合中的質數原理

Description 給出一個集合和一個數 m m m。 集合裡面有

【ZOJ - 2836 】Number Puzzle 原理

題幹: Given a list of integers (A1, A2, ..., An), and a positive integer M, please find the number of positive integers that are not greater than M

HDU-1796 How many integers can you find原理

                            How many integers can you find      

BZOJ4710 JSOI2011分特產原理+組合數學

  顯然可以容斥去掉每人都不為空的限制。每種物品分配方式獨立,各自算一個可重組合乘起來即可。 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include&

【HDOJ5514】Frogs原理

題意:n個青蛙在一個有m個節點的圓上跳,m個節點的標號為0-m-1,每隻青蛙每次跳的節點數給出,讓求n只青蛙所跳位置標號之和 n<=1e4,m<=1e9,a[i]<=1e9 思路:由裴蜀定理可知該問題等價於[0,m-1]能被至少一個gcd(m,a[i])整除的數字之和 因為n過大,考慮

hdu4135 Co-prime原理

題意:給定一個左端點L,右端點R,問L-R間有多少個數與N互質,注意1與任何數均互質。 題解:容斥原理,對N分解質因數,然後容斥原理找出這些質因數的倍數的個數,即與N不互質的數, 分別統計1-R中不互質,1-(L-1)中不互質,二者作差即為L-R中不互質,再用區間長度

2018.10.05 bzoj2393: Cirno的完美算數教室原理+搜尋

傳送門 經典題目。 顯然滿足題意的數最多不超過1024個。 然後對於兩個數a,ba,ba,b,如果aaa是bbb的倍數,那麼就不必計算aaa的貢獻。 處理出來之後容斥原理+爆搜剪枝就能過了。 程式碼:

HDU-4135 Co-prime原理模板

C - C Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descrip

Number Puzzle原理

Given a list of integers (A1, A2, …, An), and a positive integer M, please find the number of positive integers that are not greate