LOJ 3160: «NOI2019«основная боевая земля

Тема Портал: LOJ # 3160 .

Вкратце смысл вопросов:

Имеет длину \ (п- \) последовательность \ (А \) , начальная \ (a_i = я \) или \ (= a_i I ^ 2 \) , в зависимости от \ (\ mathrm {тип} \ ) из значение.

Эта последовательность \ (т \) операций, каждая операция дается значение \ (a_i \) , эта последовательность разделяется на две части: \ (A [. 1: A_i] \) и \ (а [A_i + . 1: п] \) , то предел без изменения порядка двух противоположных внутренней последовательности, эти две последовательности равномерно смешивают с образованием новой последовательности, новая последовательность \ (а \) представляет собой смесь из новая последовательность.

\ (Q \) раз после этого запроса \ (т \) После операций, значение определенной позиции \ (а_ {c_i} \) желаемого.

Решение:

Поскольку это равномерное смешивание, так что все \ (\ displaystyle БИНОМ {п} {a_i} \ \) Примесь, вероятность возникновения всех путей равны.

Сначала сделайте \ (30 \) мин \ (\ mathcal {O} ( т \ CDOT п ^ 2) \) насилие, его можно найти в образце или наблюдения: После того, как операция сделано любое количество раз, последовательность \ (\ mathbb { Е} [a_i] \) по - прежнему является функцией или квадратичной функцией.

Этот вывод может быть настолько эмоциональным пониманием:

  • Во-первых, начальная функция является квадратичной функцией или просто, чтобы доказать линейную функцию или квадратичной функции после ряда операций остаются неизменными.
  • Рассмотрим \ (\ mathbb {E} [a_i] = F (I) , \) , где \ (Р (х) \) о \ (Х \) является линейной функцией или квадратичной функцией.
  • После заданного значения \ (К \) после операции, левая секция \ (I \) член равен \ (Р (I) , \) , правая часть \ (I \) член равен \ (F (K I +) \) , обе стороны одинаковое количество функций.
  • Последовательности два линейных функции или квадратичной функции вида, соответствующей функции однородного смешивания, число которых не должны быть увеличены, но так же символы высоких коэффициентов для того, самый высокий термин заказа не будет отменены, так что число не уменьшается.

Только тогда каждый из первых трех значений могут быть получены, только первые три может быть оставлены первыми три последовательностями (которые были получены) и право из первых трех последовательностей (полученное требует интерполяции) комбинации, до тех пор, как толчок Некоторая простая формула вы можете найти новое предыдущее значение три.

Ниже приведен код, сложность \ (\ mathcal {O} (м) \) :

#include <cstdio>

typedef long long LL;
const int Mod = 998244353;
const int Inv2 = (Mod + 1) / 2;

inline int qPow(int b, int e) {
    int a = 1;
    for (; e; e >>= 1, b = (LL)b * b % Mod)
        if (e & 1) a = (LL)a * b % Mod;
    return a;
}
inline int gInv(int x) { return qPow(x, Mod - 2); }

int N, M, A, Q, Typ;
LL iN0, iN1, iN2;
int E1, E2, E3;
inline int GetX(int i) {
    if (i == 1) return E1;
    if (i == 2) return E2;
    if (i == 3) return E3;
    int SE1 = (LL)E1 * (i - 2) % Mod * (i - 3) % Mod;
    int SE2 = (LL)E2 * (2 - i - i + Mod) % Mod * (i - 3) % Mod;
    int SE3 = (LL)E3 * (i - 1) % Mod * (i - 2) % Mod;
    return ((LL)SE1 + SE2 + SE3) * Inv2 % Mod;
}

int main() {
    freopen("landlords.in", "r", stdin);
    freopen("landlords.out", "w", stdout);
    scanf("%d%d%d", &N, &M, &Typ), --Typ;
    iN0 = gInv(N), iN1 = gInv((LL)N * (N - 1) % Mod), iN2 = gInv((LL)N * (N - 1) % Mod * (N - 2) % Mod);
    E1 = 1, E2 = Typ ? 4 : 2, E3 = Typ ? 9 : 3;
    while (M--) {
        scanf("%d", &A);
        LL F1 = E1, F2 = E2, F3 = E3;
        LL F4 = GetX(A + 1), F5 = GetX(A + 2), F6 = GetX(A + 3);
        E1 = (F1 * A + F4 * (N - A)) % Mod * iN0 % Mod;
        E2 = (F2 * A % Mod * (A - 1) + (F1 + F4) * A % Mod * (N - A) + F5 * (N - A) % Mod * (N - A - 1)) % Mod * iN1 % Mod;
        E3 = (F3 * A % Mod * (A - 1) % Mod * (A - 2) + (F4 + F2 + F2) * A % Mod * (A - 1) % Mod * (N - A) + (F5 + F5 + F1) * A % Mod * (N - A) % Mod * (N - A - 1) % Mod + F6 * (N - A) % Mod * (N - A - 1) % Mod * (N - A - 2)) % Mod * iN2 % Mod;
    }
    scanf("%d", &Q);
    for (int X; Q--; ) {
        scanf("%d", &X);
        printf("%d\n", GetX(X));
    }
    return 0;
}

рекомендация

отwww.cnblogs.com/PinkRabbit/p/NOI2019D2T2.html