QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#86#23587#3264. 相逢是问候qwqQingyuFailed.2022-03-17 22:46:522022-03-17 22:46:53

詳細信息

Extra Test:

Accepted
time: 2ms
memory: 5912kb

input:

1 6 4 2
0
0 1 1
1 1 1
0 1 1
1 1 1
0 1 1
1 1 1

output:

1
2
0

result:

ok 3 lines

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#23587#3264. 相逢是问候Qingyu100 ✓347ms8644kbC++202.4kb2022-03-17 22:32:402022-04-30 03:36:20

answer

// From https://loj.ac/s/1318617
/*
 * @Date: 2021-12-07 13:41:28
 * @LastEditors: ButterCake
 * @LastEditTime: 2021-12-07 21:51:22
 */
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 5, K = 30;
int n, m, mod, c, k, p[K], cnt[N], a[N], b[N], fa[N], t[N];
int p1[K][(1 << 14) + 5], p2[K][(1 << 14) + 5];
int find(int x) {
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}
int query(int x) {
    int ret = 0;

    for (; x; x -= x & -x)
        (ret += t[x]) %= mod;

    return ret;
}
void add(int x, int y) {
    for (; x <= n; x += x & -x)
        (t[x] += y) %= mod;
}
int phi(int x) {
    int ret = x;

    for (int i = 2; i * i <= x; i++)
        if (x % i == 0) {
            ret = ret / i * (i - 1);

            while (x % i == 0)
                x /= i;
        }

    if (x > 1)
        ret = ret / x * (x - 1);

    return ret;
}
int power(int a, int b) {
    return 1ll * p1[b][a & 16383] * p2[b][a >> 14] % p[b];
}
void mdf(int i, int j) {
    int ret = b[i];

    if (ret >= p[j])
        ret = ret % p[j] + p[j];

    while (j--) {
        ret = power(ret, j);

        if (j && !ret)
            ret += p[j];
    }

    a[i] = ret;
}
int main() {
    // freopen("data.txt", "r", stdin);
    scanf("%d%d%d%d", &n, &m, &mod, &c);

    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        add(i, a[i]);
        b[i] = a[i];
    }

    for (int i = mod; i > 1; i = phi(i))
        p[k++] = i;

    p[k++] = 1;
    p[k++] = 1;

    for (int i = 0; i < k; i++) {
        for (int j = p1[i][0] = 1; j <= 1 << 14; j++)
            p1[i][j] = 1ll * p1[i][j - 1] * c % p[i];

        for (int j = p2[i][0] = 1; j < 1 << 14; j++)
            p2[i][j] = 1ll * p2[i][j - 1] * p1[i][1 << 14] % p[i];
    }

    for (int i = 1; i <= n + 1; i++)
        fa[i] = i;

    while (m--) {
        int op, l, r;
        scanf("%d%d%d", &op, &l, &r);

        // printf("op = %d, l = %d, r = %d\n", op, l, r);
        if (op == 0) {
            for (int i = find(l); i <= r; i = find(i + 1)) {
                // printf("i = %d\n", i);
                add(i, mod - a[i]);
                mdf(i, ++cnt[i]);
                add(i, a[i]);

                if (cnt[i] == k - 1)
                    fa[i] = i + 1;
            }
        } else {
            printf("%d\n", (query(r) + mod - query(l - 1)) % mod);
        }
    }

    return 0;
}