题目大意:令
F
(
a
,
b
)
F(a,b)
F(a,b)表示是否存在一个点
(
x
,
y
)
(x,y)
(x,y)使得其和
(
a
,
0
)
,
(
0
,
b
)
(a,0),(0,b)
(a,0),(0,b)围成的三角形面积是s。求
∑
a
=
1
m
F
(
a
,
n
)
+
∑
b
=
1
n
F
(
0
,
b
)
\sum_{a=1}^mF(a,n)+\sum_{b=1}^nF(0,b)
∑a=1mF(a,n)+∑b=1nF(0,b)。1000组数据,
n
=
n
1
n
2
n
3
n=n_1n_2n_3
n=n1n2n3,m和s同理,
n
i
,
m
i
,
s
i
≤
1
0
6
n_i,m_i,s_i\le10^6
ni,mi,si≤106。
题解:首先显然F(0,b)为1当且仅当b|(2s),所以
∑
b
=
1
n
F
(
0
,
b
)
\sum_{b=1}^nF(0,b)
∑b=1nF(0,b)等于2s(下文中记作S)的小于等于b的因数个数。爆搜S的因数即可。
然后我们考虑若F(a,b)有解,当且仅当至少一个点会落在
y
=
−
b
a
x
+
S
a
+
b
y=-\frac{b}{a}x+\frac{S}{a}+b
y=−abx+aS+b上,因此
a
∣
(
S
−
b
x
)
a|(S-bx)
a∣(S−bx),即
∃
y
,
b
x
+
a
y
=
S
⇒
(
a
,
b
)
∣
S
\exist y,bx+ay=S\Rightarrow (a,b)|S
∃y,bx+ay=S⇒(a,b)∣S。即这部分答案是:
∑
a
=
1
m
F
(
a
,
n
)
=
∑
a
=
1
m
[
(
a
,
n
)
∣
S
]
\sum_{a=1}^mF(a,n)=\sum_{a=1}^m[(a,n)|S]
∑a=1mF(a,n)=∑a=1m[(a,n)∣S]。注意到
(
a
,
n
)
∣
S
(a,n)|S
(a,n)∣S等价于,设质数
p
p
p在
n
n
n中指数
n
i
n_i
ni,在
S
S
S指数
S
i
S_i
Si,那么若
n
i
>
S
i
n_i>S_i
ni>Si,则
p
p
p在
a
a
a中指数
a
i
≤
s
i
a_i\le s_i
ai≤si。注意到这玩意可以容斥,并且由于前16小的质数乘积就爆
1
0
18
10^{18}
1018了,因此复杂度是对的。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define lint long long
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
using namespace std;typedef pair<int,int> pii;const int N=1000000+2;int p[N],mnp[N],np[N];
inline int inn() { int x,ch;while((ch=gc)<'0'||ch>'9');x=ch^'0';while((ch=gc)>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^'0');return x; }
inline int prelude(int n) { for(int i=2,c=0;i<=n;i++) { if(!np[i]) p[++c]=i,mnp[i]=i;rep(j,1,c&&p[j]<=n/i) { int x=p[j]*i;np[x]=1,mnp[x]=p[j];if(i%p[j]==0) break; } } return 0; }
struct Int{
int vis[N],cnt;pii v[20];lint val[20];inline int init() { rep(i,1,cnt) vis[v[i].fir]=0;return cnt=0; }
inline lint value()const { lint x=1;rep(i,1,cnt) x*=val[i];return x; }
inline int add(int x) { for(int t;(t=mnp[x]);) { if(!vis[t]) vis[t]=++cnt,v[cnt]=mp(t,0),val[cnt]=1;int p=vis[t];while(x%t==0) x/=t,v[p].sec++,val[p]*=t; } return 0; }
inline lint dfs(int x,lint s,lint n)const { if(x==cnt+1) return s<=n;if(s>n) return 0;lint ans=0;rep(j,0,v[x].sec) if(s<=n) ans+=dfs(x+1,s,n),s*=v[x].fir;else break;return ans; }
inline int getcnt(int x)const { if(!vis[x]) return 0;return v[vis[x]].sec; }
inline lint qwq(int x)const { if(!vis[x]) return x;return x*val[vis[x]]; }
}n,m,s;
namespace SOLVE1_space{
const int S=(1<<16)+2;lint xz[20],val[S];int sz[S],id[S];
inline lint solve(const Int &n,lint m,const Int &s)
{
int cnt=0;rep(i,1,n.cnt) if(n.v[i].sec>s.getcnt(n.v[i].fir)) xz[cnt++]=s.qwq(n.v[i].fir);
int all=(1<<cnt)-1;lint ans=0;val[0]=1;rep(i,0,cnt-1) id[1<<i]=i;
rep(i,1,all) sz[i]=sz[i>>1]+(i&1),val[i]=val[i^(i&(-i))]*xz[id[i&-i]];
rep(i,0,all) if(sz[i]&1) ans-=m/val[i];else ans+=m/val[i];return ans;
}
}
namespace SOLVE2_space{ inline lint solve(lint n,const Int &s) { return s.dfs(1,1,n); } }
int main()
{
prelude(N-1);
for(int T=inn();T;T--)
{
n.init(),m.init(),s.init();rep(i,0,2) n.add(inn());rep(i,0,2) m.add(inn());rep(i,0,2) s.add(inn());s.add(2);
printf("%lld\n",SOLVE1_space::solve(n,m.value(),s)+SOLVE2_space::solve(n.value(),s));
}
return 0;
}