QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#1068#551010#9242. An Easy Geometry Problemucup-team5405ucup-team004Failed.2024-10-25 14:48:522024-10-25 14:48:52

Details

Extra Test:

Accepted
time: 0ms
memory: 3820kb

input:

6 6 6 2
1 5 9 10 15 18
2 2
1 3 3 -3
2 2
1 3 4 3
2 3
2 4

output:

1
0
2
0

result:

ok 4 number(s): "1 0 2 0"

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#551010#9242. An Easy Geometry Problemucup-team004#AC ✓721ms15884kbC++206.2kb2024-09-07 15:04:092024-09-07 15:04:09

answer

#include <bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
// TODO: Dynamic ModInt

template<typename T>
constexpr T power(T a, u64 b) {
    T res {1ULL};
    for (; b != 0; b /= 2, a *= a) {
        if (b % 2 == 1) {
            res *= a;
        }
    }
    return res;
}

template<u32 P>
constexpr u32 mulMod(u32 a, u32 b) {
    return 1ULL * a * b % P;
}

template<u64 P>
constexpr u64 mulMod(u64 a, u64 b) {
    u64 res = a * b - u64(1.L * a * b / P - 0.5L) * P;
    res %= P;
    return res;
}

template<typename U, U P>
requires std::unsigned_integral<U>
struct ModIntBase {
public:
    constexpr ModIntBase() : x {0} {}
    
    template<typename T>
    requires std::integral<T>
    constexpr ModIntBase(T x_) : x {norm(x_ % T {P})} {}
    
    constexpr static U norm(U x) {
        if ((x >> (8 * sizeof(U) - 1) & 1) == 1) {
            x += P;
        }
        if (x >= P) {
            x -= P;
        }
        return x;
    }
    
    constexpr U val() const {
        return x;
    }
    
    constexpr ModIntBase operator-() const {
        ModIntBase res;
        res.x = norm(P - x);
        return res;
    }
    
    constexpr ModIntBase inv() const {
        return power(*this, P - 2);
    }
    
    constexpr ModIntBase &operator*=(const ModIntBase &rhs) & {
        x = mulMod<P>(x, rhs.val());
        return *this;
    }
    
    constexpr ModIntBase &operator+=(const ModIntBase &rhs) & {
        x = norm(x + rhs.x);
        return *this;
    }
    
    constexpr ModIntBase &operator-=(const ModIntBase &rhs) & {
        x = norm(x - rhs.x);
        return *this;
    }
    
    constexpr ModIntBase &operator/=(const ModIntBase &rhs) & {
        return *this *= rhs.inv();
    }
    
    friend constexpr ModIntBase operator*(ModIntBase lhs, const ModIntBase &rhs) {
        lhs *= rhs;
        return lhs;
    }
    
    friend constexpr ModIntBase operator+(ModIntBase lhs, const ModIntBase &rhs) {
        lhs += rhs;
        return lhs;
    }
    
    friend constexpr ModIntBase operator-(ModIntBase lhs, const ModIntBase &rhs) {
        lhs -= rhs;
        return lhs;
    }
    
    friend constexpr ModIntBase operator/(ModIntBase lhs, const ModIntBase &rhs) {
        lhs /= rhs;
        return lhs;
    }
    
    friend constexpr std::ostream &operator<<(std::ostream &os, const ModIntBase &a) {
        return os << a.val();
    }
    
    friend constexpr bool operator==(ModIntBase lhs, ModIntBase rhs) {
        return lhs.val() == rhs.val();
    }
    
    friend constexpr bool operator!=(ModIntBase lhs, ModIntBase rhs) {
        return lhs.val() != rhs.val();
    }
    
    friend constexpr bool operator<(ModIntBase lhs, ModIntBase rhs) {
        return lhs.val() < rhs.val();
    }
    
private:
    U x;
};

template<u32 P>
using ModInt = ModIntBase<u32, P>;

template<u64 P>
using ModInt64 = ModIntBase<u64, P>;

constexpr u64 P = u64(1E18) + 9;
using Z = ModInt64<P>;

constexpr u64 B = 1145141;
template <typename T>
struct Fenwick {
    int n;
    std::vector<T> a;
    
    Fenwick(int n_ = 0) {
        init(n_);
    }
    
    void init(int n_) {
        n = n_;
        a.assign(n, T{});
    }
    
    void add(int x, const T &v) {
        for (int i = x + 1; i <= n; i += i & -i) {
            a[i - 1] = a[i - 1] + v;
        }
    }
    
    T sum(int x) {
        T ans{};
        for (int i = x; i > 0; i -= i & -i) {
            ans = ans + a[i - 1];
        }
        return ans;
    }
    
    T rangeSum(int l, int r) {
        return sum(r) - sum(l);
    }
    
    int select(const T &k) {
        int x = 0;
        T cur{};
        for (int i = 1 << std::__lg(n); i; i /= 2) {
            if (x + i <= n && cur + a[x + i - 1] <= k) {
                x += i;
                cur = cur + a[x - 1];
            }
        }
        return x;
    }
};

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int n, q;
    i64 k, b;
    std::cin >> n >> q >> k >> b;
    
    std::vector<i64> A(n);
    for (int i = 0; i < n; i++) {
        std::cin >> A[i];
        A[i] = 2 * A[i] - k * i;
    }
    b *= 2;
    
    Fenwick<Z> f1(n);
    Fenwick<Z> f2(n);
    Fenwick<Z> f3(n);
    
    std::vector<Z> pw(n + 1), pwinv(n + 1);
    std::vector<Z> sp(n + 1), spi(n + 1);
    pw[0] = 1ULL;
    pwinv[0] = 1ULL;
    Z inv = Z(B).inv();
    for (int i = 1; i <= n; i++) {
        pw[i] = pw[i - 1] * B;
        pwinv[i] = pwinv[i - 1] * inv;
    }
    for (int i = 0; i < n; i++) {
        sp[i + 1] = sp[i] + pw[i];
        spi[i + 1] = spi[i] + pwinv[i];
    }
    
    for (int i = 0; i < n; i++) {
        f1.add(i, A[i] * pw[i]);
        f2.add(i, A[i] * pwinv[i]);
    }
    
    while (q--) {
        int o;
        std::cin >> o;
        if (o == 1) {
            int l, r;
            i64 v;
            std::cin >> l >> r >> v;
            l--;
            
            v *= 2;
            
            f1.add(r, v * sp[r]);
            f1.add(l, -v * sp[l]);
            f2.add(r, v * spi[r]);
            f2.add(l, -v * spi[l]);
            f3.add(r, v);
            f3.add(l, -v);
        } else {
            int i;
            std::cin >> i;
            i--;
            
            int lo = 0, hi = std::min(i, n - 1 - i);
            while (lo < hi) {
                int r = (lo + hi + 1) / 2;
                Z hl;
                Z hr;
                hl += f2.sum(i);
                hl += f3.rangeSum(i, n) * spi[i];
                hl -= f2.sum(i - r);
                hl -= f3.rangeSum(i - r, n) * spi[i - r];
                hl *= pw[i - 1];
                
                hr += f1.sum(i + r + 1);
                hr += f3.rangeSum(i + r + 1, n) * sp[i + r + 1];
                hr -= f1.sum(i + 1);
                hr -= f3.rangeSum(i + 1, n) * sp[i + 1];
                hr *= pwinv[i + 1];
                if (hl + b * sp[r] == hr) {
                    lo = r;
                } else {
                    hi = r - 1;
                }
            }
            std::cout << lo << "\n";
        }
    }
    
    return 0;
}