QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#754452#9631. Median ReplacementGolem__TL 0ms3636kbC++2012.5kb2024-11-16 15:04:562024-11-16 15:04:57

Judging History

你现在查看的是最新测评结果

  • [2024-11-16 15:04:57]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3636kb
  • [2024-11-16 15:04:56]
  • 提交

answer

// [Irelia]
#include<bits/stdc++.h>

namespace Irelia // [Irelia Library] Irelia
{
    #define Irelia__ 201307
    #define fcc(i, j, k) for(num (i)=(j); (i)<=(k); ++(i))
    #define ccf(i, j, k) for(num (i)=(j); (i)>=(k); --(i))
    #define I (*this)
    #define same_type(T1, T2) (std::is_same<T1, T2>::value)
    #define num_type(T) (same_type(T, num) || same_type(T, Num))
    #define fra_type(T) (same_type(T, fra) || same_type(T, Fra))
    #define num_or_fra_type(T) (num_type(T) || fra_type(T))

    using num = int;
    using Num = long long;
    using unum = unsigned int;
    using uNum = unsigned long long;
    using fra = double;
    using Fra = long double;
    using pnum = std::pair<num, num>;
    using pNum = std::pair<Num, Num>;
    template<typename T>
    using heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

    const char newl = '\n', *snewl = " \n";

    constexpr Num read()
    {
        Num ret = 0, s = 1, c = getchar();
        for(; !isdigit(c); c = getchar()) if(c == '-') s = -1;
        for(; isdigit(c); c = getchar()) ret = (ret << 1) + (ret << 3) + (c ^ 48);
        return s * ret;
    }
    constexpr std::string readstr()
    {
        std::string ret; char c;
        for(; (c = getchar()) <= ' ';);
        for(; c > ' '; c = getchar()) ret += c;
        return ret;
    }
    template<typename T>
    constexpr void min_(T &a, auto &&b) { if(b < a) a = b; }
    template<typename T>
    constexpr void max_(T &a, auto &&b) { if(a < b) a = b; }
    template<typename Tnf> requires num_or_fra_type(Tnf)
    constexpr Tnf inf() { return (std::numeric_limits<Tnf>::max() - Irelia__) / 2; }
    template<typename Tn> requires num_type(Tn)
    constexpr Tn lowbit(Tn i) { return i & -i; }

    template<typename T>
    class vector : private std::vector<T>
    {
        public:
        using iterator = std::vector<T>::iterator;
        iterator begin() { return std::vector<T>::begin(); }
        iterator end() { return std::vector<T>::end(); }

        vector() { }
        vector(num siz) : std::vector<T>(siz) { }
        vector(num siz, auto &&t) : std::vector<T>(siz, t) { }
        vector(std::initializer_list<T> il) : std::vector<T>(il) { }
        vector(T *pb, T *pe) : std::vector<T>(pb, pe) { }
        vector(iterator itb, iterator ite) : std::vector<T>(itb, ite) { }

        void clear() { std::vector<T>::clear(); }
        operator bool () { return !I.empty(); }
        num size() { return std::vector<T>::size(); }
        vector &set(num siz) { return I.resize(siz), I; }
        T &front() { return std::vector<T>::front(); }
        T &back() { return std::vector<T>::back(); }
        T &operator [] (num i)
        {
            #ifdef DEBUG__
            assert(0 <= i && i < size());
            #endif
            return std::vector<T>::operator[](i);
        }
        void push(auto &&...t) { I.emplace_back(t...); }
        void insert(num i, auto &&...t) { I.emplace(begin() + i, t...); }
        void pop() { I.pop_back(); }
        void erase(num i) { std::vector<T>::erase(begin() + i); }
        void fill(auto &&t) { std::fill(begin(), end(), t); }
        void reverse() { std::reverse(begin(), end()); }
        template<typename Tcom = std::less<T>>
        void sort() { std::sort(begin(), end(), Tcom()); }
        template<typename Tcom = std::less<T>>
        num lower(auto &&t) { return std::lower_bound(begin(), end(), t, Tcom()) - begin(); }
        template<typename Tcom = std::less<T>>
        num upper(auto &&t) { return std::upper_bound(begin(), end(), t, Tcom()) - begin(); }
        template<typename Tcom = std::less<T>>
        void discretize()
        {
            sort<Tcom>(), set(std::unique(begin(), end(),
                [&](T &a, T &b) { return !Tcom()(a, b) && !Tcom()(b, a); }) - begin());
        }
    };

    #define every(e, G, o) for(num (e)=(G).las[(o)]; (e); (e)=(G).pre[(e)])
    template<typename Tn> requires num_type(Tn)
    class graph
    {
        public:
        num V, E; vector<num> las, pre, to, fro; vector<Tn> wei, cap;

        graph(num V = 0) : V(V), E(0), las(V + 1), pre(2), to(2), fro(2), wei(2), cap(2) { }

        void add(num u, num v, Tn w = 0, Tn c = 0)
        { pre.push(las[u]), las[u] = ++E + 1, to.push(v), fro.push(u), wei.push(w), cap.push(c); }
        void addb(num u, num v, Tn w = 0, Tn c = 0) { add(u, v, w, c), add(v, u, w, c); }
    };
}

namespace Irelia // [Irelia Library] modulus
{
    template<num mod>
    class modnum
    {
        private:
        num i;

        public:
        modnum(num i = 0) : i(i) { }

        num operator () () { return i; }
        modnum &operator ++ () { if(++i == mod) i = 0; return I; }
        modnum operator ++ (num) { modnum ret = I; return ++I, ret; }
        modnum operator + (modnum m) { num ret = i + m.i; if(ret >= mod) ret -= mod; return ret; }
        modnum &operator += (modnum m) { if((i += m.i) >= mod) i -= mod; return I; }
        modnum &operator -- () { if(!i--) i = mod - 1; return I; }
        modnum operator -- (num) { modnum ret = I; return --I, ret; }
        modnum operator - () { num ret = i ? mod - i : 0; return ret; }
        modnum operator - (modnum m) { num ret = i - m.i; if(ret < 0) ret += mod; return ret; }
        modnum &operator -= (modnum m) { if((i -= m.i) < 0) i += mod; return I; }
        modnum operator * (modnum m) { return 1ULL * i * m.i % mod; }
        modnum &operator *= (modnum m) { return i = 1ULL * i * m.i % mod, I; }
        modnum operator / (modnum m) { return I * m.inv(); }
        modnum &operator /= (modnum m) { return I *= m.inv(); }
        modnum power(num e)
        { modnum ret = 1, d = I; for(; e; e >>= 1, d *= d) if(e & 1) ret *= d; return ret; }
        modnum inv() { return power(mod - 2); }
        friend std::ostream &operator << (std::ostream &os, modnum m) { return std::cout << m.i; }
    };
}

namespace Irelia // [Irelia Library] poly
{
    template<num mod, num pr>
    class poly : public vector<modnum<mod>>
    {
        static poly ur;

        public:
        using iterator = vector<modnum<mod>>::iterator;

        poly() { }
        poly(num len) : vector<modnum<mod>>(len) { }
        poly(std::initializer_list<modnum<mod>> il) : vector<modnum<mod>>(il) { }
        poly(modnum<mod> *pb, modnum<mod> *pe) : vector<modnum<mod>>(pb, pe) { }
        poly(iterator itb, iterator ite) : vector<modnum<mod>>(itb, ite) { }

        poly &set(num len) { return vector<modnum<mod>>::set(len), I; }
        static void set_ur(num len)
        {
            if(ur.size() < len)
            {
                num las = ur.size(); ur.set(len);
                for(num d = las; d < len; d <<= 1)
                    ur[d] = modnum<mod>(pr).power((mod - 1 >> 2) / d);
                fcc(i, las, len - 1) ur[i] = ur[i ^ lowbit(i)] * ur[lowbit(i)];
            }
        }
        void NTT(num len)
        {
            modnum<mod> t; set_ur(len >> 1);
            if(I.size() < len) set(len);
            for(num d = len >> 1; d; d >>= 1)
                for(num i = 0, u = 0; i < len; i += d << 1, ++u)
                    for(num j = i, k = i + d; j < i + d; ++j, ++k)
                        t = I[k] * ur[u], I[k] = I[j] - t, I[j] += t;
        }
        void INTT(num len)
        {
            modnum<mod> t; set_ur(len >> 1);
            if(I.size() < len) set(len);
            for(num d = 1; d < len; d <<= 1)
                for(num i = 0, u = 0; i < len; i += d << 1, ++u)
                    for(num j = i, k = i + d; j < i + d; ++j, ++k)
                        t = I[k], I[k] = (I[j] - I[k]) * ur[u], I[j] += t;
            std::reverse(I.begin() + 1, I.end()), t = modnum<mod>(len).inv();
            fcc(i, 0, len - 1) I[i] *= t;
        }
        poly operator + (auto &&P) { return poly(I) += P; }
        poly &operator += (auto &&P)
        { if(I.size() < P.size()) set(P.size()); fcc(i, 0, P.size() - 1) I[i] += P[i]; return I; }
        poly operator - (auto &&P) { return poly(I) -= P; }
        poly &operator -= (auto &&P)
        { if(I.size() < P.size()) set(P.size()); fcc(i, 0, P.size() - 1) I[i] -= P[i]; return I; }
        poly operator * (auto &&P) { return poly(I) *= P; }
        poly &operator *= (auto &&P)
        {
            num len = I.size() + P.size() - 1, bc = std::bit_ceil<unum>(len);
            if(len < 100)
            {
                poly R(len);
                fcc(i, 0, I.size() - 1) fcc(j, 0, P.size() - 1) R[i + j] += I[i] * P[j];
                return I = R;
            }
            NTT(bc), P.NTT(bc);
            fcc(i, 0, bc - 1) I[i] *= P[i];
            return INTT(bc), set(len);
        }
        poly inv()
        {
            num bc = std::bit_ceil<unum>(I.size()); poly P, Q, R({ I[0].inv() });
            for(num d = 2; d <= bc; d <<= 1)
            {
                P = poly(I.begin(), I.begin() + std::min(I.size(), d)), Q = R;
                P.NTT(d << 1), Q.NTT(d << 1);
                fcc(i, 0, (d << 1) - 1) P[i] *= Q[i] * Q[i];
                P.INTT(d << 1), R = R + R - P.set(d);
            }
            return R.set(I.size());
        }
        poly operator / (auto &&P) { return poly(I) /= P; }
        poly &operator /= (auto &&P) { return I *= P.inv(); }
        poly deriv() { poly R(I.size()); fcc(i, 1, I.size() - 1) R[i - 1] = I[i] * i; return R; }
        poly integ() { poly R(I.size()); fcc(i, 1, I.size() - 1) R[i] = I[i - 1] / i; return R; }
        poly ln() { return (deriv() * inv()).integ(); }
        poly exp()
        {
            poly P = deriv(), Q, R(I.size());
            std::function<void(num, num)> DAC = [&](num l, num r)
            {
                if(l == r) return l ? (R[l] /= l) : (R[l] = 1), void();
                num m = l + r >> 1; DAC(l, m);
                Q = poly(R.begin() + l, R.begin() + m + 1) * poly(P.begin(), P.begin() + r - l);
                fcc(i, m + 1, r) R[i] += Q[i - l - 1];
                DAC(m + 1, r);
            };
            return DAC(0, I.size() - 1), R;
        }
        modnum<mod> operator () (modnum<mod> x)
        { modnum<mod> y = 0; ccf(i, I.size() - 1, 0) y = y * x + I[i]; return y; }
        static poly Lagrange(vector<modnum<mod>> X, vector<modnum<mod>> Y)
        {
            #ifdef DEBUG__
            assert(X.size() == Y.size());
            #endif
            num len = X.size(); poly P(len + 1), Q, R(len); P[0] = 1;
            fcc(i, 0, len - 1) ccf(j, i, 0) P[j + 1] += P[j], P[j] *= -X[i];
            fcc(i, 0, len - 1)
            {
                modnum<mod> mul = 1;
                fcc(j, 0, len - 1) if(i != j) mul *= X[i] - X[j];
                mul = Y[i] / mul, Q = P;
                ccf(j, len - 1, 0) R[j] += Q[j + 1] * mul, Q[j] += Q[j + 1] * X[i];
            }
            return R;
        }
    };
    template<num mod, num pr>
    poly<mod, pr> poly<mod, pr>::ur({ modnum<mod>(1) });
}

using namespace Irelia;

const num mod = 1E9 + 7;
using Mod = modnum<mod>;
using Poly = poly<mod, 3>;
void solve()
{
    num N = read(), D;
    vector<num> L(N + 1), R(N + 1), dis({ 0, 1 });
    fcc(i, 1, N) L[i] = read(), dis.push(L[i]);
    fcc(i, 1, N) R[i] = read(), dis.push(R[i] + 1);
    dis.discretize(), D = dis.size() - 1;
    Mod ans = 0, mul = 1;
    fcc(i, 1, N) mul *= R[i] - L[i] + 1;
    auto work = [&](num x)
    {
        vector<std::array<Mod, 3>> dp(N + 1);
        fcc(j, 0, 2) dp[0][j] = 1;
        fcc(i, 1, N) fcc(j, 0, 2)
        {
            if(L[i] < x) dp[i][j] = dp[i - 1][std::max(0, j - 1)] * (std::min(R[i] + 1, x) - L[i]);
            if(!j && R[i] >= x) dp[i][j] += dp[i - 1][2] * (R[i] - std::max(L[i], x) + 1);
        }
        return mul - dp[N][0];
    };
    fcc(d, 1, D - 1)
    {
        num l = dis[d], r = dis[d + 1] - 1;
        fcc(x, l, r) ans += work(x);
        // if(r - l + 1 <= N + 1) fcc(x, l, r) ans -= work(x);
        // else
        // {
        //     Poly X(N + 1), Y(N + 1);
        //     fcc(i, 0, N) X[i] = i + l, Y[i] = work(i + l);
        //     Poly P = Poly::Lagrange(X, Y);
        //     fcc(i, l, r) assert(P(i)() == work(i)());
        //     P.push(0), P = P.integ(), ans -= P(r) - P(l - 1);
        // }
    }
    std::cout << ans << newl;
}
num main()
{
    #ifndef ONLINE_JUDGE
    freopen(".in", "r", stdin);
    freopen(".out", "w", stdout);
    #endif
    std::ios::sync_with_stdio(0), std::cin.tie(0);

    for(num T = read(); T --> 0;) solve();
    return 0 ^ 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3636kb

input:

10
5
5 1 4 3 2
14 2 5 3 2
5
4 5 1 2 3
13 7 1 2 3
5
5 2 5 3 1
10 2 12 3 2
5
5 5 3 1 5
57 5 3 1 5
5
2 2 3 3 5
4 5 4 4 5
5
4 5 3 5 3
13 7 3 5 3
5
5 1 4 2 3
14 3 4 2 3
5
1 2 5 4 5
2 8 5 7 5
5
1 1 3 5 1
8 2 3 8 1
5
4 4 4 2 3
5 10 5 2 3

output:

180
170
650
265
182
173
120
296
192
131

result:

ok 10 lines

Test #2:

score: 0
Accepted
time: 0ms
memory: 3620kb

input:

10
5
1 2 2 5 3
6 4 2 6 3
5
4 4 1 4 3
6 7 2 5 3
5
5 3 4 2 4
5 7 5 2 6
5
1 5 3 5 2
7 7 3 5 2
5
1 3 3 2 2
10 5 3 2 2
5
4 4 4 5 3
4 11 9 5 3
5
5 3 2 1 3
13 5 2 1 5
5
5 4 1 2 5
10 6 1 2 5
5
3 5 3 4 2
5 9 3 5 2
5
1 1 3 2 1
7 3 3 3 1

output:

120
230
144
110
110
289
324
89
140
122

result:

ok 10 lines

Test #3:

score: 0
Accepted
time: 0ms
memory: 3600kb

input:

10
5
3 1 3 4 4
9 1 3 10 4
5
1 1 3 1 1
9 1 3 3 1
5
5 1 2 3 1
74 1 2 3 1
5
2 5 5 3 4
5 6 8 3 4
5
2 1 3 4 5
2 4 6 4 5
5
2 4 2 1 3
2 11 3 2 3
5
1 5 4 4 2
1 14 6 6 2
5
4 1 3 5 1
9 2 4 5 1
5
4 1 2 4 4
6 1 6 4 4
5
3 2 5 3 5
8 8 5 3 5

output:

196
76
140
172
72
80
486
84
65
224

result:

ok 10 lines

Test #4:

score: -100
Time Limit Exceeded

input:

10
5
676437428 903889545 700650370 965758082 146716866
676437431 903889567 700650370 965758082 146716866
5
517457740 64600397 388618400 783268973 388618400
517457797 64600397 388618400 783268973 388618400
5
971452763 106948541 259878781 537741075 9504353
971452780 106948544 259878781 537741075 95043...

output:


result: