2020牛客暑期多校训练营(第九场)- E. Groundhog Chasing Death

题目链接: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)}$,接下来考虑一下a*i和b*j的大小

当$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(a*i,b*j)}=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的总的幂次(幂次加的过程中需要欧拉降幂),然后快速幂求解即可

#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;
}

 

posted on 2020-08-08 17:10  啊啊鄂  阅读(310)  评论(0编辑  收藏  举报

导航