TrickGCD(容斥原理 & 篩數 & 好題)
很容易想到我們要列舉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&
2018.11.18 spoj Triple Sums(容斥原理+fft)
傳送門 這次 f f t fft
【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