题目链接:Groundhog Chasing Death

题意:给你一个a,b,c,d,x,y,求$\prod_{i=a}^{b} \prod_{j=c}^{d} gcd(x^i,y^j)$的值

思路:对x,y质因数分解,对于x和y的某一个公共质因子p,假设x分解后p的幂次为a,y分解后p的幂次位为b,当i,j确定时,p对答案贡献为$p^{min(a*i,b*j)}$,接下来考虑一下ai和bj的大小

当$j\geq \lceil \frac{a*i}{b} \rceil$时有$a*i\leq b*j$,此时$p^{min(a*i,b*j)}=p^{a*i}$

当$j< \lceil \frac{a*i}{b} \rceil$时有$a*i>b*j$,此时$p^{min(ai,bj)}=p^{b*j}$

对于每个p,我们可以枚举i,显然$\lceil \frac{a*i}{b} \rceil$时确定的

对于$\geq \lceil \frac{a*i}{b} \rceil$的j来说,p的幂次为$a*i*(d- \lceil \frac{a*i}{b} \rceil +1)$

对于$< \lceil \frac{a*i}{b} \rceil$的j来说,p的幂次为$b*[c+(c+1)+\dots +(\lceil \frac{a*i}{b} \rceil -1)]$

算出每个p的总的幂次(幂次加的过程中需要欧拉降幂),然后快速幂求解即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <vector>

using namespace std;

typedef long long ll;

const int N = 3000010;
const ll mod = 998244353;

struct node {
int a, b;
node() { }
node(int ta, int tb) : a(ta), b(tb) { }
};

int a, b, c, d, x, y;
int px[N], cx[N], py[N], cy[N], mx, my;
vector<node> v;
vector<int> alls;
ll mi[N];

void divide(int n, int *p, int *c, int &m)
{
m = 0;
for (int i = 2; i <= sqrt(n); i++) {
if (0 != n % i) continue;
p[++m] = i;
c[m] = 0;
while (0 == n % i) {
n /= i;
c[m] += 1;
}
}
if (n > 1) {
p[++m] = n;
c[m] = 1;
}
}

ll power(ll a, ll n)
{
ll res = 1;
while (n) {
if (n & 1) res = res * a % mod;
a = a * a % mod;
n >>= 1;
}
return res;
}

int get_id(int x)
{
return lower_bound(alls.begin(), alls.end(), x) - alls.begin() + 1;
}

int main()
{
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d%d%d%d%d%d", &a, &b, &c, &d, &x, &y);
divide(x, px, cx, mx);
divide(y, py, cy, my);
int ppx = 1, ppy = 1;
while (ppx <= mx && ppy <= my) {
if (px[ppx] == py[ppy]) {
v.push_back(node(cx[ppx], cy[ppy]));
alls.push_back(px[ppx]);
ppx += 1;
ppy += 1;
}
else if (px[ppx] < py[ppy]) ppx += 1;
else ppy += 1;
}
for (int i = a; i <= b; i++) {
for (int k = 0; k < v.size(); k++) {
int mia = v[k].a, mib = v[k].b, id = get_id(alls[k]);
int j = (i * mia + mib - 1) / mib;
if (j > d) {
ll t = 1ll * (c + d) * (d - c + 1) / 2;
mi[id] = (mi[id] + t * mib) % (mod - 1);
}
else if (j < c) {
ll t = d - c + 1;
mi[id] = (mi[id] + t * mia * i) % (mod - 1);
}
else {
ll ta = 1ll * (c + j - 1) * (j - c) / 2, tb = d - j + 1;
mi[id] = (mi[id] + ta * mib) % (mod - 1);
mi[id] = (mi[id] + tb * mia * i) % (mod - 1);
}
}
}
ll res = 1;
for (int i = 1; i <= alls.size(); i++) {
if (0 == mi[i]) continue;
ll t = power(alls[i - 1], mi[i]);
res = res * t % mod;
}
printf("%lld\n", res);
return 0;
}