随机TLE求调
查看原帖
随机TLE求调
589961
steambird楼主2024/5/28 14:11

rt,有时AC有时TLE#10

#include <bits/stdc++.h>
using namespace std;

inline void train() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

constexpr int N = 2e5+4;

vector<long long> assigner;
vector<long long>::iterator ae;

// Persistent array, allowing single-point update and multi-point query:
// NOTICE THAT FOR ALL QUESTIONS YOU NEED TO MODIFY THIS.

// Another example: Dynamically Construct Something

template <typename Ty>
inline int maxi(Ty a, Ty b) {
    return a > b ? a : b;
}

template <typename Ty>
inline int mini(Ty a, Ty b) {
    return a < b ? a : b;
}

template <typename data, int size, int maxsize>
class persistant_array {
    public:

        struct array_node {
            data storage;
            int lnode, rnode, lref, rref;
        };

        // [S Raise To-Do after 2 templates: Add range modifier.]
        void update(int version, int ver_origin, int where, data value) {
            // Emplace a root if needed or insert
            if (!version_src.count(version)) {
                version_src[version] = emplace_for(1, ns, version_src[ver_origin]);
#ifndef ONLINE_JUDGE
                cerr << "Creating version " << version << endl;
#endif // ONLINE_JUDGE
                update_internal(version_src[version], version_src[ver_origin], where, value);
            } else {
                cerr << "Update error: Version " << version << " already exists" << endl;
                throw exception();
            }
        }

        data query(int version, int where) {
            if (version_src.count(version)) {
                return query_internal(version_src[version], where);
            } else {
                cerr << "Update error: Version " << version << " not exist" << endl;
                throw exception();
            }
        }

        data query(int version, int l, int r) {
            if (version_src.count(version)) {
                return query_internal(version_src[version], l, r);
            } else {
                cerr << "Update error: Version " << version << " not exist" << endl;
                throw exception();
            }
        }

        void copy_version(int version, int origin) {
            //version_src[version] = version_src[origin];
            version_src[version] = emplace_for(1, ns, version_src[origin]);
        }

/*
        persistant_array(function<data,data&> pushdown, function<data,data,data&> pushup, data default_val)
            : pushdown(pushdown), pushup(pushup), default_val(default_val) {
            version_src[0] = build(1, size, default_val);
        }
*/

        /*
        void construct(data *origins, int n = size) {
            this->origins = origins;
            ns = n;
            version_src[0] = build(1, n);
        }
        */


        void construct(data default_val, int n = size) {
            this->default_val = default_val;
            ns = n;
            version_src[0] = build(1, n, default_val);
        }

        persistant_array() : default_val(data()) {

        }


    private:
        array_node stree[maxsize];


        int build(int l, int r, data default_val) {
            if (l > r) return -1;
            int my = assigner++;
            stree[my].lnode = l;
            stree[my].rnode = r;
            if (l == r) {
                stree[my].storage = default_val;
                return my;
            }
            int mid = (l+r) >> 1;
            int ls = stree[my].lref = build(l, mid, default_val);
            int rs = stree[my].rref = build(mid+1, r, default_val);
            pushup(stree[ls].storage, stree[rs].storage, stree[my].storage);
            return my;
        }

        /*
        int build(int l, int r) {
            if (l > r) return -1;
            int my = assigner++;
            stree[my].lnode = l;
            stree[my].rnode = r;
            if (l == r) {
                //stree[my].storage = default_val;
                stree[my].storage = origins[l];
                return my;
            }
            int mid = (l+r) >> 1;
//            stree[my].lref = build(l, mid, default_val);
            int ls = stree[my].lref = build(l, mid);
//            stree[my].rref = build(mid+1, r, default_val);
            int rs = stree[my].rref = build(mid+1, r);
            pushup(stree[ls].storage, stree[rs].storage, stree[my].storage);
            return my;
        }
        */

        int emplace_for(int l, int r, int origin) {
            int my = assigner++;
            stree[my].lnode = l;
            stree[my].rnode = r;
            //stree[my].storage = default_val;
            stree[my].storage = stree[origin].storage;  // ** TO MODIFY **
            stree[my].lref = stree[origin].lref;
            stree[my].rref = stree[origin].rref;
            return my;
        }

        void update_internal(int root, int origin, int where, data value) {
            if (stree[root].lnode == where && stree[root].rnode == where) {
                stree[root].storage += value;
#ifndef ONLINE_JUDGE
                cerr << "Modifying " << where << " as " << value << endl;
#endif // ONLINE_JUDGE
                return;
            }
            int mid = (stree[root].lnode + stree[root].rnode) >> 1;
            if (where <= mid) {
                stree[root].lref = emplace_for(stree[root].lnode, mid, stree[origin].lref);
                //pushdown(stree[root].storage, stree[stree[root].lref].storage);
                update_internal(stree[root].lref, stree[origin].lref, where, value);
            } else {
                stree[root].rref = emplace_for(mid+1, stree[root].rnode, stree[origin].rref);
                //pushdown(stree[root].storage, stree[stree[root].rref].storage);
                update_internal(stree[root].rref, stree[origin].rref, where, value);
            }

            pushup(stree[stree[root].lref].storage, stree[stree[root].rref].storage, stree[root].storage);
#ifndef ONLINE_JUDGE
            cerr << "Pushup [" << stree[root].lnode << "," << stree[root].rnode << "] = " << stree[root].storage << endl;
#endif // ONLINE_JUDGE
        }

        data query_internal(int root, int where) {
            if (stree[root].lnode == where && stree[root].rnode == where) {
                return stree[root].storage;
            }
            int mid = (stree[root].lnode + stree[root].rnode) >> 1;
            if (where <= mid) {
                return query_internal(stree[root].lref, where);
            } else {
                return query_internal(stree[root].rref, where);
            }
        }

        data query_internal(int root, int l, int r) {
            if (l > r) return this->default_val;
            if (stree[root].lnode >= l && stree[root].rnode <= r) {
                return stree[root].storage;
            }
            int mid = (stree[root].lnode + stree[root].rnode) >> 1;
            data fin;
            data lq = query_internal(stree[root].lref, maxi(l, stree[root].lnode), mini(mid, r));
            data rq = query_internal(stree[root].rref, maxi(mid+1, l), mini(stree[root].rnode, r));
            pushup(lq, rq, fin);
            return fin;
        }

        //function<data,data&> pushdown;

        //function<data,data,data&> pushup;
        void pushup(data left, data right, data &root) {
            root = left + right;
        }


        unordered_map<int, int> version_src;

        int assigner = 0, ns;
        data default_val;
        //data *origins;
};

// End.

int n, m, a[N];
persistant_array<int, N, int(4e6)> ptree;

// [l, r]
inline int fetch_value_for(int l, int r, int rel) {
    //int rel = lower_bound(assigner.begin(), ae, pos) - assigner.begin() + 1;
    //eturn ptree.query(r, rel) - ptree.query(l-1, rel);
    auto rp = ptree.query(r, 1, rel), lp = ptree.query(l-1, 1, rel);
#ifndef ONLINE_JUDGE
    cerr << "fetch [" << l << "," << r <<"] for " << rel << ": " << rp << "-" << lp << endl;
#endif // ONLINE_JUDGE
    return rp-lp;
}

int main() {
    train();

    cin>>n>>m;
    for (int i = 1; i <= n; i++) {
        cin>>a[i];
        assigner.push_back(a[i]);
    }
    sort(assigner.begin(), assigner.end());
    ae = unique(assigner.begin(), assigner.end());
    size_t dsz = ae - assigner.begin();
    ptree.construct(0, dsz);
    for (int i = 1; i <= n; i++) {
        int rel = lower_bound(assigner.begin(), ae, a[i]) - assigner.begin() + 1;
#ifndef ONLINE_JUDGE
        cerr << "Update at " << rel << endl;
#endif // ONLINE_JUDGE
        ptree.update(i, i-1, rel, 1);
#ifndef ONLINE_JUDGE
        cerr << "END -- Update at " << rel << endl;
#endif // ONLINE_JUDGE
    }
    for (int qs = 0; qs < m; qs++) {
        int l,r,k;
        cin>>l>>r>>k;
        int al = -1, ar = dsz+1;
        while (al+1<ar) {
            int mid = (al + ar) >> 1;
            // Check mid.
            int res = fetch_value_for(l, r, mid + 1);
#ifndef ONLINE_JUDGE
            cerr << "Reaching " << mid << " (number " << assigner[mid] << ") has " << res << " number(s)" << endl;
#endif // ONLINE_JUDGE

            if (res >= k) {
                // Too large
                ar = mid;
            } else {
                al = mid;
            }
        }
        cout<<assigner[ar]<<'\n';
    }

    cout<<flush;
    return 0;
}

2024/5/28 14:11
加载中...