——杭电多校赛第九场E
0⩽a,b,c,d⩽3×106,0
这里还要用到一个原理就是指数可能会爆long long 所以就是用到一个欧拉降幂,原理我也是看不懂,但是公式记住先。在快速幂取模时指数对mod-1取余,其他还是不变对mod取余。或者这里就是可以用_int128来做哦。
#include
using namespace std;
typedef long long ll;
const ll mod = 998244353;
const ll md = 998244352;
vector<pair<ll,ll> > v;
void div(ll n)
{
v.clear();
ll k = sqrt(n);
for (ll i = 2; i <= k; ++ i) {
ll cnt = 0;
while (n % i == 0) {
n /= i;
cnt ++;
}
v.push_back({i, cnt});
}
if (n != 1) {
v.push_back({n, 1});
}
}
ll phi(ll n)
{
ll ans = n;
ll k = sqrt(n);
for (int i = 2; i <= k; ++i) {
if (n % i == 0) {
ans = ans / i * (i - 1);
while (n % i == 0) n /= i;
}
}
if (n > 1) {
ans = ans / n * (n - 1);
}
return ans;
}
ll pow(ll a, ll b, ll p) {
ll res = 1;
while (b) {
if (b & 1) res = (res * a) % p;
a = a * a % p;
b >>= 1;
}
return res%p;
}
int main()
{
ll a, b, c, d, x, y;
scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &x, &y);
a = max(1LL, a);
c = max(1LL, c);
--c;
div(x);
ll ans = 1;
for (int i = 0; i < (int)v.size(); ++ i) {
ll cnt = 0;
while (y % v[i].first == 0) {
y /= v[i].first;
++ cnt;
}
ll sum = 0;
if (cnt == 0) continue;
for (ll j = a; j <= b; ++ j) {
ll e = v[i].second * (ll)j;
ll f = e/cnt;
while (cnt * f < e) {
++ f;
}
if (c >= f) {
sum -= ((f * (f-1) / 2)% md * (cnt % md)) % md;
sum = (sum % md + md) % md;
sum -= (ll)(((c-f+1) % md) * (e % md)) % md;
sum = (sum % md + md) % md;
}
else {
sum -= ((c * (c+1) / 2) % md * (cnt % md)) % md;
sum = (sum % md + md) % md;
}
sum = (sum % md + md) % md;
if (d >= f) {
sum += ((f * (f-1) / 2) % md) * (cnt % md) % md;
sum = (sum % md + md) % md;
sum += (ll)(((d-f+1) % md) * (e % md)) % md;
sum = (sum % md + md) % md;
}
else {
sum += (((d * (d+1) /2) % md) * (cnt) % md) % md;
sum = (sum % md + md) % md;
}
}
sum = (sum % md + md) % md;
ans *= pow(v[i].first, sum, mod);
ans = (ans % mod + mod) % mod;
}
ans = (ans % mod + mod) % mod;
printf("%lld\n", ans);
return 0;
}