【CF819C】Mister B and Beacons on Field 數學

【CF819C】Mister B and Beacons on Field

題意外星人盯上了Farmer Jack的農場!咱們假設FJ的農場是一個二維直角座標系,FJ的家在原點。外星人向FJ的農場上投放了3個信標,不幸的是,有一個信標落地就徹底損壞了,且不知道具體位置,其他兩個信標分別被投放到了 $(m,0)​$ 和 $(0,n)$ 處。ios

FJ對這些新的金閃閃的東西很感興趣,他決定將這兩個信標搬到家裏去。具體地,FJ先從 $(0,0)$ 沿着 $x$ 軸走到 $(m,0)$ ,撿起信標,而後沿着 $x$ 軸返回 $(0,0)$ ,把信標放到家中。再從 $(0,0)$ 沿着 $y$ 軸走到 $(0,n)$ ,撿起信標,而後沿着 $y$ 軸返回 $(0,0)$ ,把信標放到家中。spa

然而那兩個沒有損壞的信標在一直與外星人保持聯繫,它們一直在試圖尋找那個損壞的信標的位置。具體地,當兩個未損壞的信標的座標都是整數時,若是存在平面上的一個整點,知足這個點與兩個未損壞的信標組成的三角形面積爲 $s$ ,則兩個信標會向外星人發送一次信息。如今外星人想知道,在搬運的整個過程當中,這兩個信標一共會向外星人發送多少次信息?
code

t組數據,$n=n_1\cdot n_2\cdot n_3$,$m,s$同理,$n_1,n_2,n_3...\le 10^6$blog

題解:先s*=2,而後分紅兩段考慮:string

從 $(n,0)$ 到 $(0,0)$ :由於這段簡單就先考慮這段。若是當前走到 $(0,i)$ ,顯然$i|s$就行了,因此枚舉s的全部$\le n$約數便可。it

從 $(m,0)$ 到 $(0,0)$ :考慮將面積轉化成叉積的形式。若是當前走到 $(i,0)$ ,就變成問你$i\cdot y+(x-i)n=s$有沒有整數解。根據裴蜀定理這個東西有整數解當且僅當$gcd(i,n)|s$。而後考慮容斥,若是$d=gcd(i,n)\nmid s$,則d中至少有一個質因子的係數大於s對應項的係數。因此答案等於至少0項的-至少1項的+至少2項的。。。io

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
ll n,m,s,ans;
int tot;
int pn[60],pm[60],ps[60],pri[60];
ll xp[60];
int vis[1000010];
inline void solve(int *cnt,int x)
{
	for(int i=2;i*i<=x;i++)	if(x%i==0)
	{
		if(!vis[i])	vis[i]=++tot,pri[tot]=i;
		while(x%i==0)	x/=i,cnt[vis[i]]++;
	}
	if(x>1)
	{
		if(!vis[x])	vis[x]=++tot,pri[tot]=x;
		cnt[vis[x]]++;
	}
}
inline void init()
{
	memset(pn,0,sizeof(pn)),memset(pm,0,sizeof(pm)),memset(ps,0,sizeof(ps));
	for(int i=1;i<=tot;i++)	vis[pri[i]]=0;
}
void dfs1(int x,ll now)
{
	if(now>n)	return ;
	if(x>tot)
	{
		ans++;
		return ;
	}
	dfs1(x+1,now);
	for(int i=1;i<=ps[x];i++)	dfs1(x+1,now*=pri[x]);
}
void dfs2(int x,ll now,int flag)
{
	if(now>m)	return ;
	if(x>tot)
	{
		ans+=flag*(m/now);
		return ;
	}
	dfs2(x+1,now,flag);
	if(pn[x]>ps[x])	dfs2(x+1,now*xp[x]*pri[x],-flag);
}
inline void work()
{
	int t;
	n=m=s=1,ans=tot=0;
	scanf("%d",&t),solve(pn,t),n*=t,scanf("%d",&t),solve(pn,t),n*=t,scanf("%d",&t),solve(pn,t),n*=t;
	scanf("%d",&t),solve(pm,t),m*=t,scanf("%d",&t),solve(pm,t),m*=t,scanf("%d",&t),solve(pm,t),m*=t;
	scanf("%d",&t),solve(ps,t),s*=t,scanf("%d",&t),solve(ps,t),s*=t,scanf("%d",&t),solve(ps,t),s*=t;
	solve(ps,2),s<<=1;
	dfs1(1,1);
	for(int i=1,j;i<=tot;i++)	for(j=xp[i]=1;j<=ps[i];j++)	xp[i]*=pri[i];
	dfs2(1,1,1);
	printf("%lld\n",ans);
	init();
}
int main()
{
	freopen("beacon.in","r",stdin);
	freopen("beacon.out","w",stdout);
	int T;
	scanf("%d",&T);
	while(T--)	work();
	return 0;
}//1 10 6 18 2 103 2 13 1 13
相關文章
相關標籤/搜索