QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#394928 | #1375. TripTik | WisdomCasual | TL | 8ms | 32112kb | C++20 | 4.2kb | 2024-04-20 22:02:49 | 2024-04-20 22:02:49 |
Judging History
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...