제출 #1188437

#제출 시각아이디문제언어결과실행 시간메모리
118843712345678Fish 2 (JOI22_fish2)C++17
8 / 100
199 ms18836 KiB
#include <bits/stdc++.h>

using namespace std;

#define ll long long

const int nx=1e5+5;

ll n, a[nx], q, t, l, r, ql, qr;

struct segtreesum
{
    ll d[4*nx];
    void build(int l, int r, int i)
    {
        if (l==r) return d[i]=a[l], void();
        int md=(l+r)/2;
        build(l, md, 2*i);
        build(md+1, r, 2*i+1);
        d[i]=d[2*i]+d[2*i+1];
    }
    void update(int l, int r, int i, int idx, ll vl)
    {
        if (idx<l||r<idx) return;
        if (l==r) return d[i]=vl, void();
        int md=(l+r)/2;
        update(l, md ,2*i, idx, vl);
        update(md+1, r, 2*i+1, idx, vl);
        d[i]=d[2*i]+d[2*i+1];
    }
    ll query(int l, int r, int i, int ql, int qr)
    {
        if (qr<l||r<ql||qr<ql) return 0;
        if (ql<=l&&r<=qr) return d[i];
        int md=(l+r)/2;
        return query(l, md ,2*i, ql, qr)+query(md+1, r, 2*i+1, ql, qr);
    }
} sm;

struct segtreeleft
{
    // qs[i]-qs[l-1] < a[i+1] -> qs[i]-a[i+1] < qs[l-1]
    ll d[4*nx], lz[4*nx];
    void apply(int i, ll vl)
    {
        d[i]+=vl;
        lz[i]+=vl;
    }
    void pushlz(int i)
    {
        apply(2*i, lz[i]);
        apply(2*i+1, lz[i]);
        lz[i]=0;
    }
    void build(int l, int r, int i)
    {
        if (l==r) return d[i]=sm.query(1, n, 1, 1, l)-a[l+1], void();
        int md=(l+r)/2;
        build(l, md, 2*i);
        build(md+1, r, 2*i+1);
        d[i]=min(d[2*i], d[2*i+1]);
    }
    void update(int l, int r, int i, int ql, int qr, ll vl)
    {
        if (qr<l||r<ql) return;
        if (ql<=l&&r<=qr) return apply(i, vl);
        int md=(l+r)/2;
        pushlz(i);
        update(l, md, 2*i, ql, qr ,vl);
        update(l, md, 2*i, ql, qr, vl);
        d[i]=min(d[2*i], d[2*i+1]);
    }
    ll query(int l, int r, int i, int ql, int qr, ll vl)
    {
        if (qr<l||r<ql||d[i]>=vl) return ql-1;
        if (l==r) return l;
        int md=(l+r)/2;
        pushlz(i);
        auto tmp=query(md+1, r, 2*i+1, ql, qr, vl);
        if (tmp<ql) return query(l, md, 2*i, ql, qr, vl);
        return tmp;
    }
    void queryfill(int l, int r, int i, int ql, int qr, ll vl, vector<int> &v)
    {
        if (qr<l||r<ql||d[i]>=vl) return;
        if (l==r) return v.push_back(l), void();
        int md=(l+r)/2;
        pushlz(i);
        queryfill(l, md, 2*i, ql, qr, vl, v);
        queryfill(md+1, r, 2*i+1, ql, qr ,vl, v);
    }
} ls;

struct segtreeright
{
    // qs[r] - qs[i-1] < a[i-1] -> qs[r] < a[i-1] + qs[i-1]
    ll d[4*nx], lz[4*nx];
    void apply(int i, ll vl)
    {
        d[i]+=vl;
        lz[i]+=vl;
    }
    void pushlz(int i)
    {
        apply(2*i, lz[i]);
        apply(2*i+1, lz[i]);
        lz[i]=0;
    }
    void build(int l, int r, int i)
    {
        if (l==r) return d[i]=sm.query(1, n, 1, 1, l-1)+a[l-1], void();
        int md=(l+r)/2;
        build(l, md, 2*i);
        build(md+1, r, 2*i+1);
        d[i]=max(d[2*i], d[2*i+1]);
    }
    void update(int l, int r, int i, int ql, int qr, ll vl)
    {
        if (qr<l||r<ql) return;
        if (ql<=l&&r<=qr) return apply(i, vl);
        int md=(l+r)/2;
        pushlz(i);
        update(l, md, 2*i, ql, qr ,vl);
        update(l, md, 2*i, ql, qr, vl);
        d[i]=max(d[2*i], d[2*i+1]);
    }
    ll query(int l, int r, int i, int ql, int qr, ll vl)
    {
        if (qr<l||r<ql||d[i]<=vl) return qr+1;
        if (l==r) return l;
        int md=(l+r)/2;
        pushlz(i);
        auto tmp=query(l, md, 2*i, ql, qr, vl);
        if (tmp>qr) return query(md+1, r, 2*i+1, ql, qr, vl);
        return tmp;
    }
    void queryfill(int l, int r, int i, int ql, int qr, ll vl, vector<int> &v)
    {
        if (qr<l||r<ql||d[i]<=vl) return;
        //if (l==r) cout<<"debug "<<l<<' '<<d[i]<<' '<<vl<<'\n';
        if (l==r) return v.push_back(l), void();
        int md=(l+r)/2;
        pushlz(i);
        queryfill(l, md, 2*i, ql, qr, vl, v);
        queryfill(md+1, r, 2*i+1, ql, qr ,vl, v);
    }
} rs;

struct segtreefreq
{
    struct node
    {
        ll mn, f, lz;
        node(): mn(1e18), f(0), lz(0){}
    } d[4*nx];
    void apply(int i, ll vl)
    {
        d[i].mn+=vl;
        d[i].lz+=vl;
    }
    void pushlz(int i)
    {
        apply(2*i, d[i].lz);
        apply(2*i+1, d[i].lz);
        d[i].lz=0;
    }
    node merge(node l, node r)
    {
        node res;
        res.mn=min(l.mn, r.mn);
        res.f=(l.f*(l.mn==res.mn))+(r.f*(r.mn==res.mn));
        return res;
    }
    void build(int l, int r, int i)
    {
        if (l==r) return d[i].mn=0, d[i].f=1, d[i].lz=0, void();
        int md=(l+r)/2;
        build(l, md, 2*i);
        build(md+1, r, 2*i+1);
        d[i]=merge(d[2*i], d[2*i+1]);
    }
    void update(int l, int r, int i, int ql, int qr, ll vl)
    {
        if (qr<l||r<ql) return;
        if (ql<=l&&r<=qr) return apply(i, vl);
        int md=(l+r)/2;
        pushlz(i);
        update(l, md, 2*i, ql, qr ,vl);
        update(md+1, r, 2*i+1, ql, qr, vl);
        d[i]=merge(d[2*i], d[2*i+1]);
    }
    void show(int l, int r, int i)
    {
        //cout<<"show "<<l<<' '<<r<<' '<<i<<'\n';
        if (l==r) return cout<<l<<' '<<d[i].mn<<' '<<d[i].f<<'\n', void();
        int md=(l+r)/2;
        pushlz(i);
        show(l, md, 2*i);
        show(md+1, r, 2*i+1);
    }
    node query(int l, int r, int i, int ql, int qr)
    {
        if (qr<l||r<ql) return node();
        if (ql<=l&&r<=qr) return d[i];
        int md=(l+r)/2;
        pushlz(i);
        return merge(query(l, md, 2*i, ql, qr), query(md+1, r, 2*i+1, ql, qr));
    }
} fs;

void addrange(int l, int r)
{
    //cout<<"addrange "<<l<<' '<<r<<'\n';
    fs.update(1, n, 1, l, r, 1);
    //cout<<"after "<<fs.d[1].mn<<' '<<fs.d[1].f<<'\n';
}

int main()
{
    cin.tie(NULL)->sync_with_stdio(false);
    cin>>n;
    for (int i=1; i<=n; i++) cin>>a[i];
    a[0]=a[n+1]=1e18;
    sm.build(1, n, 1);
    ls.build(1, n, 1);
    rs.build(1, n, 1);
    fs.build(1, n, 1);
    for (int i=1; i<=n; i++)
    {
        vector<int> p;
        rs.queryfill(1, n, 1, 1, i, sm.query(1, n, 1, 1, i), p);
        for (auto x:p) if (sm.query(1, n, 1, x, i)<a[i+1]) addrange(x, i);
    }
    //fs.show(1, n, 1);
    cin>>q;
    while (q--)
    {
        cin>>t>>l>>r;
        cout<<fs.query(1, n, 1, l, r).f<<'\n';
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...