QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#394928#1375. TripTikWisdomCasualTL 8ms32112kbC++204.2kb2024-04-20 22:02:492024-04-20 22:02:49

Judging History

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

  • [2024-04-20 22:02:49]
  • 评测
  • 测评结果:TL
  • 用时:8ms
  • 内存:32112kb
  • [2024-04-20 22:02:49]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#define ERROR ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); fileIO();
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
void fileIO(){
    #ifndef ONLINE_JUDGE
    freopen("io\\input.txt", "r", stdin);
    freopen("io\\output.txt", "w", stdout);
    #endif
}

const ll mod = 1e9 + 7, N = 1e5 + 5, CAM = 32, inf = 1e18;

vector<vector<ll>> minCost(N, vector<ll>(CAM, inf));

ll n, k;
struct Node {
    vector<ll> v;

    Node() {
    }
    Node operator+(Node other) {
        for(auto i : v)
            other.v.push_back(i);
        sort(other.v.begin(), other.v.end(), greater<ll>());
        Node ret;
        for(ll i = 0; i < min(k, (ll)other.v.size()); i++)
            ret.v.push_back(other.v[i]);
        return ret;
    }
};

struct SegTree {
    private:
    vector<Node> tree;
    ll n;

    Node build(ll node, ll s, ll e, vector<pair<ll, ll>>& v) {
        if(s == e) {
            tree[node].v.push_back(v[s].second);
            return tree[node];
        }
        ll mid = (s+e) >> 1;
        return tree[node] = build(node*2, s, mid, v) + build(node*2+1, mid+1, e, v);
    }

    Node query(ll node, ll s, ll e, ll l, ll r) {
        if(l > e || r < s) return Node();
        if(s >= l && e <= r) return tree[node];
        ll mid = (s+e) >>1;
        return query(node*2, s, mid, l, r) + query(node*2+1, mid+1, e, l, r);
    }


    public:
    SegTree(vector<pair<ll, ll>>& v) {
        n = v.size();
        ll sz = 1;
        while(sz < n)
            sz*=2;
        sz*=2;
        tree = vector<Node>(sz);
        build(1, 0, n-1, v);
    }

    vector<ll> query(ll l, ll r) {
        return query(1, 0, n-1, l, r).v;
    }
};

void TestCase(){

    cin >> n >> k;

    // location, weight
    pair<ll, ll> points[n+1];
    vector<pair<ll, ll>> v(n+1);

    points[0] = {0, 0};
    v[0] = points[0];
    vector<ll> ans(n+1, inf);

    for(ll i = 1; i <= n; i++){
        cin >> points[i].first;
        points[i].second = i;
        v[i] = points[i];
    }

    sort(v.begin(), v.end());

    SegTree st(v);

    priority_queue<pair<ll, pair<ll, ll>>> pq;
        //cost, point index, camSize(log 2)

    for(ll i = 0; i < CAM; i++){
        pq.push({-i, {0, i}});
        minCost[0][i] = i;
    }

    while(pq.size()){

        ll cost =  -pq.top().first;
        ll point = pq.top().second.first;
        ll camInc = pq.top().second.second;
        pq.pop();
        
        ans[point] = min(ans[point], cost + camInc + 1);

        if(cost > minCost[point][camInc])
            continue;
        
        {
            ll l = lower_bound(v.begin(), v.end(), make_pair(points[point].first - (1ll << camInc), -inf)) - v.begin();
            ll r = prev(upper_bound(v.begin(), v.end(), make_pair(points[point].first + (1ll << camInc), inf))) - v.begin();
            vector<ll> visible = st.query(l, r);

            for(auto visiblePoint : visible){
                if(visiblePoint == point){
                    ans[point] = min(ans[point], cost);
                    break;
                }
            }
        }

        for(ll i = 0; i < CAM; i++){
            ll newCost = cost + abs(camInc - i) + 1;
            ll newCamInc = i;
            
            ll l = lower_bound(v.begin(), v.end(), make_pair(points[point].first - (1ll << i), -inf)) - v.begin();
            ll r = prev(upper_bound(v.begin(), v.end(), make_pair(points[point].first + (1ll << i), inf))) - v.begin();
            if(l > r) continue;
            vector<ll> visible = st.query(l, r);
            for(auto newpoint : visible){
                if(newpoint == 0 || newpoint == point) continue;
                if(newCost < minCost[newpoint][newCamInc]){
                    minCost[newpoint][newCamInc] = newCost;
                    pq.push({-newCost, {newpoint, newCamInc}});
                }
            }
        }

    }

    for(ll i = 1; i <= n; i++){
        if(ans[i] == inf)
            cout << -1 << '\n';
        else
            cout << ans[i] << '\n';
    }

}

int main() {
    
    ERROR;

    ll t = 1;
    //cin >> t;

    while(t--)
        TestCase();

}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 8ms
memory: 32112kb

input:

4 2
-2
-1
-3
2

output:

3
1
3
2

result:

ok 4 lines

Test #2:

score: -100
Time Limit Exceeded

input:

100000 4
-81032899
-96819000
35569221
67767248
74154777
75473369
3463319
18339682
-77145048
-26587182
-22902096
-55717109
-47237134
-44620229
-45753774
33183854
-15569807
72648777
-33842373
44545672
-48017305
71506102
33448860
-20688896
6205313
21527590
24985350
-14688810
29596074
-47051603
-9258675...

output:


result: