제출 #1092321

#제출 시각아이디문제언어결과실행 시간메모리
1092321DeathIsAweToll (BOI17_toll)C++17
100 / 100
167 ms77136 KiB
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
int segment[131072];
const int maxi = 1000000000;
int graph[50000][5][15][5];


void add(int pos, int a) {
    pos += 65536;
    segment[pos] = a;
    pos /= 2;
    while (pos > 0) {
        if (segment[2*pos + 1] == -1 || segment[2*pos] == -1) {
            segment[pos] = -1;
        } else {
            segment[pos] = segment[2*pos + 1] + segment[2*pos];
        }
        pos /= 2;
    }
}


int find(int a, int b) {
    a += 65536; b += 65536 - 1;
    int val = 0;
    while (a <= b) {
        if (a % 2 == 1) {
            if (segment[a] == -1) {
                val = -1; break;
            }
            val += segment[a++];
        }
        if (b % 2 == 0) {
            if (segment[b] == -1) {
                val = -1; break;
            }
            val += segment[b--];
        }
        a /= 2; b /= 2;
    }
    if (val == 0) {
        return -1;
    }
    return val;
}


int main() {
    int k, n, m, o, d1, d2, t; cin >> k >> n >> m >> o;
    if (k == 1) {
        for (int i=0;i<131072;i++) {
            segment[i] = -1;
        }
        for (int i=0;i<m;i++) {
            cin >> d1 >> d2 >> t;
            add(d1, t);
        }
        for (int i=0;i<o;i++) {
            cin >> d1 >> d2;
            cout << find(d1, d2) << '\n';
        }
        return 0;
    }
    int asdf = (n + k - 1) / k;
    for (int i=0;i<50000;i++) {
        for (int j=0;j<k;j++) {
            for (int x=0;x<15;x++) {
                for (int y=0;y<k;y++) {
                    graph[i][j][x][y] = maxi;
                }
            }
        }
    }
    for (int i=0;i<m;i++) {
        cin >> d1 >> d2 >> t;
        graph[d1/k][d1%k][0][d2%k] = t;
    }
    int add = 1;
    for (int i=1;i<15;i++) {
        for (int j=0;j<asdf;j++) {
            for (int x=0;x<k;x++) {
                for (int y=0;y<k;y++) {
                    for (int z=0;z<k;z++) {
                        graph[j][x][i][y] = min(graph[j][x][i][y], graph[j][x][i-1][z] + graph[j + add][z][i-1][y]);
                        if (graph[j][x][i][y] > maxi) {
                            graph[j][x][i][y] = maxi;
                        }
                    }
                }
            }
        }
        add *= 2;
    }


    int ans[5], newans[5], pow2, pow2val, diff, amodk, adivk, bmodk, bdivk;
    for (int i=0;i<o;i++) {
        cin >> d1 >> d2;
        amodk = d1 % k; adivk = d1 / k;
        bmodk = d2 % k; bdivk = d2 / k;
        pow2val = 16384; pow2 = 14;
        diff = bdivk - adivk;
        if (diff <= 0) {
            cout << -1 << '\n'; continue;
        }
        while (true) {
            if (diff < pow2val) {
                pow2val /= 2;
                pow2 -= 1;
                continue;
            }
            diff -= pow2val;
            //cout << pow2 << '\n';
            for (int j=0;j<k;j++) {
                ans[j] = graph[adivk][amodk][pow2][j];
            }
            adivk += pow2val;
            pow2val /= 2;
            pow2 -= 1;
            break;
        }
        //cout << ans[0] << ' ' << ans[2] << ' ' << adivk << ' ' << pow2 << '\n';


        while (diff > 0) {
            if (diff < pow2val) {
                pow2val /= 2;
                pow2 -= 1;
                continue;
            }
            diff -= pow2val;
            for (int j=0;j<k;j++) {
                newans[j] = maxi;
                for (int x=0; x<k;x++) {
                    if (graph[adivk][x][pow2][j] < maxi && ans[x] < maxi) {
                        newans[j] = min(newans[j], graph[adivk][x][pow2][j] + ans[x]);
                    }
                }
            }
            for (int j=0;j<k;j++) {
                ans[j] = newans[j];
            }
            adivk += pow2val;
            pow2val /= 2;
            pow2 -= 1;
        }
        if (ans[bmodk] == maxi) {
            cout << -1 << '\n'; continue;
        }
        cout << ans[bmodk] << '\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...