1. 程式人生 > >BZOJ2301 容斥原理,莫比烏斯反演

BZOJ2301 容斥原理,莫比烏斯反演

Description

對於給出的n個詢問,每次求有多少個數對(x,y),滿足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函式為x和y的最大公約數。

資料範圍:100%的資料滿足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000

做法:

第一次嘗試寫莫比烏斯反演的模板。由於對該演算法不是很熟悉,就不講莫比烏斯反演的部分了。

用solve(s,t)表示1<=x<=s,1<=y<=t時的答案。那麼所求的答案為

solve(b,d)-solve(a-1,d)-solve(b,c-1)+solve(a-1,c-1)

然後用莫比烏斯反演求解solve就好了。

模板借鑑了各位學長和大神的。

注:BZOJ用cin會RE,這個程式碼在洛谷上交就沒問題,在BZOJ上交要改scanf

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int miu[50010];
int sum[50010];
int prime[50010];
bool notprm[50010];
const int MAXN=50001;
int cnt;
long long ans;
int a,b,c,d,k;
void init()
{
	miu[1]=1;
	for(int i=2;i<=MAXN;++i)
	{
		if(!notprm[i])
		{
			prime[cnt++]=i;
			miu[i]=-1;
		}
		for(int j=0;j<cnt&&i*prime[j]<=MAXN;++j)
		{
			notprm[i*prime[j]] = 1;
			if(i%prime[j])miu[i*prime[j]]=-miu[i];
			else
			{
				miu[i*prime[j]]=0;  
                break;
			}
		}
	}
	for(int i=1;i<=MAXN;++i)
		sum[i]=sum[i-1]+miu[i];
}
long long solve(int x,int y)
{
	long long res=0;
	if(x>y)swap(x,y);
	for(long long i=1,l=0;i<=x;i=l+1)
	{
		l=min(x/(x/i),y/(y/i));
		res+=(sum[l]-sum[i-1])*(x/i)*(y/i);
	}
	return res;
}
int main()
{
	init();
	int T;
	cin>>T;
	while(T--)
	{
		cin>>a>>b>>c>>d>>k;
		if(a>b||c>d)
		{
			cout<<0<<endl;
			continue;
		}
		ans=solve(b/k,d/k);
        ans-=solve((a-1)/k,d/k);
        ans-=solve(b/k,(c-1)/k);
        ans+=solve((a-1)/k,(c-1)/k);
        cout<<ans<<endl;
	}
}


相關推薦

BZOJ2301 原理,

Description 對於給出的n個詢問,每次求有多少個數對(x,y),滿足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函式為x和y的最大公約數。 資料範圍:100%的資料滿足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,

5468 Puzzled Elena (dfs序+原理/

題目:給出一棵樹,每個點上有權值.然後求每棵子樹中與根節點互質 即gcd(a,b)=1 的節點個數. 思路:該題涉及到一個典型問題.問x與S中有多少個數不互素。解決辦法是將S中所有元素依次進行兩個步驟:①將元素進行質因數分解。②將質因數可能產生的乘積的出現次數加1。記錄一下

+分塊優化-BZOJ2301

對於給出的n個詢問,每次求有多少個數對(x,y),滿足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函式為x和y的最大公約數。 Input 第一行一個整數n,接下來n行每行五個整數,分別表示a、b、c、d、k Output 共n行,

【CF900D】Unusual Sequences

div blog mic names include sin 題意 方案 ace 【CF900D】Unusual Sequences 題意:定義正整數序列$a_1,a_2...a_n$是合法的,當且僅當$gcd(a_1,a_2...a_n)=x$且$a_1+a_2+...

BZOJ4833: [Lydsy1704月賽]最小公倍佩爾數(min-max&)(線性多項式多個數求LCM)

4833: [Lydsy1704月賽]最小公倍佩爾數 Time Limit: 8 Sec  Memory Limit: 128 MBSubmit: 240  Solved: 118[Submit][Status][Dis

BZoj 2301 Problem b(定理+

2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MB Submit: 7732  Solved: 3750 [Submit][Statu

UESTC 618 無平方因子數 ()

無平方因子數 Time Limit: 4000/2000MS (Java/Others)    Memory Limit: 65535/65535KB (Java/Others) Submit  S

BZOJ 2440 完全平方數 (+二分)

2440: [中山市選2011]完全平方數 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1673  Solved: 799 [Submit][Status][Discuss] Description 小 X 自幼就

codeforces 839D (推公式+原理/函式)

Winter is here at the North and the White Walkers are close. John Snow has an army consisting of n soldiers. While the rest of the

BZOJ2301 Problem B 【】【分塊】

題解: 對於 a≤x≤b,c≤y≤da≤x≤b,c≤y≤d,這個條件,我們發現比較難以處理,這時候我們可以利用二維字首和的思想,記 x≤b,y≤dx≤b,y≤d 時的答案為 A[b][d]A[b]

bzoj2301 [HAOI2011]Problem b(求gcd==k的個數)(+原理

首先我們搞掉下界,怎麼搞呢,用容斥原理即可。(看做矩形區間),然後我們需要求∑x=1n∑y=1ngcd(x,y)==k。 ∑x=1⌊n/k⌋∑y=1⌊m/k⌋gcd(x,y)==1 ∑x=1⌊n/k

2301: [HAOI2011]Problem b +字首+原理

Description 對於給出的n個詢問,每次求有多少個數對(x,y),滿足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函式為x和y的最大公約數。 Input 第一行一個整數n,接下來n行每行五個整數,分別表示a、b、c、d、k

poj 3904 原理

poj 3904 莫比烏斯反演 或 容斥原理 題目: 給出n個數字a1,a2,...an, 求從中選出一個四元組(a,b,c,d), 使得gcd(a,b,c,d)=1,求符合條件的四元組的數目。 限制

[BZOJ2301]Problem b +

題意明確,就是求∑i=ab∑j=cdgcd(i,j)==k 首先容易發現容斥定理,轉化為求 ∑i=1n∑j=1mgcd(i,j)==k 我們設f(d)=∑i=1n∑j=1m(gcd(i,j)==d

5072 單色三角形++原理

單色三角形:如果每個人都有關係的話,認識或者不認識,隨便找6個人(或以上),則一定會有三個人互相認識,或者互相不認識。因為每個人和其他人都有關係嘛,認識或者不認識。則一個人A與其他5個人有都有關係,這個時候當A與其他5個人的關係中有兩個認識,3個不認識(或者2個

JZYZOJ1518 [haoi2011]b 分塊

namespace tar ios closed 速度 esp 計算 i++ pac http://172.20.6.3/Problem_Show.asp?id=1518最開始只想到了n^2的寫法,肯定要超時的,所以要對求gcd的過程進行優化。首先是前綴和容斥,很好理解。第

bzoj 2005 & 洛谷 P1447 [ Noi 2010 ] 能量采集 —— /

return int line algo std 個數 所有 col 括號 題目:bzoj 2005 https://www.lydsy.com/JudgeOnline/problem.php?id=2005    洛谷 P1447 https://www.luogu.

[NOI2010]能量採集[,]

題意 計算,表示在範圍內的個數 資料範圍: 題解 這裡介紹容斥和莫比烏斯反演兩種方法(如果想系統瞭解這種題目的各種大體思路可以看兩兩gcd求和的4種方法) 下面先設分別為為​​​​​​倍數和等於的個數,有 容斥(篩法) 容斥是利用先計算到每個,再通過從後向前處

6053 TrickGCD(+思想+分塊字首和技巧)

題目大意: 給你一個數組 A ,問你有多少不大於 A 的陣列 B 使得 B 中所有元素的最大公因數不為1。(陣列 B 不大於陣列 A 就等價於,對於任意 A 陣列中的元素 a [ i ] 和 B 陣列中對應元素 b [ i ] ,均有:a [ i ] >

TrickGCD(+定理)

連結:http://acm.hdu.edu.cn/showproblem.php?pid=6053 hdu6053 TrickGCD 題目解析: 令sum[k]為k能夠出現的個數 eg: Input 3 6 6 9 各個數字出現的情況 1 1 1 2 2 2 3 3