Submission #944775

# Submission time Handle Problem Language Result Execution time Memory
944775 2024-03-13T04:39:00 Z salmon Meetings (IOI18_meetings) C++14
Compilation error
0 ms 0 KB
#include <bits/stdc++.h>
#include "meetings.h"
using namespace std;

int N;
int Q;
int lst[250100];
long long int num[200100][25];
pair<int,int> st[500100];
pair<int,int> st1[500100];


void build(int i, int s, int e){
    if(s == e){
        st[i] = {lst[s],s};
        st1[i] = {lst[s],-s};
        return;
    }

    int m = (s + e)/2;

    build(i * 2,s,m);
    build(i * 2 + 1, m + 1, e);

    st[i] = max(st[i * 2],st[i * 2 + 1]);
    st1[i] = max(st1[i * 2],st1[i * 2 + 1]);
}

pair<int,int> query(int i, int s, int e, int S, int E){
    if(S <= s && e <= E){
        return st[i];
    }

    int m = (s + e)/2;

    if(S <= m && m < E){
        return max(query(i*2,s,m,S,E), query(i*2+1,m+1,e,S,E));
    }

    if(S <= m) return query(i * 2, s, m ,S, E);
    if(m < E) return query(i * 2 + 1, m + 1, e, S, E);
}

pair<int,int> query1(int i, int s, int e, int S, int E){
    if(S <= s && e <= E){
        return st1[i];
    }

    int m = (s + e)/2;

    if(S <= m && m < E){
        return max(query1(i*2,s,m,S,E), query1(i*2+1,m+1,e,S,E));
    }

    if(S <= m) return query1(i * 2, s, m ,S, E);
    if(m < E) return query1(i * 2 + 1, m + 1, e, S, E);
}


long long int recurse(int j, int l ,int r){
    if(l > r) return 0;
    if(l == r && lst[l] == j){
        num[l][j] = 0;
        return j;
    }

    long long int small = 1e18;

    vector<int> temp = {l - 1};

    for(int i = l; i <= r; i++){
        if(lst[i] == j) temp.push_back(i);
    }

    temp.push_back(r + 1);

    for(int i = 0; i < temp.size() - 1; i++){
        long long int vum = recurse(j - 1,temp[i] + 1, temp[i + 1] - 1) + (temp[i] - l + 1 + r - temp[i + 1] + 1) * j;
        small = min(small, vum);
        num[temp[i + 1] - 1][j] = vum - (r - l + 1) * j;
    }

    return small;
}

struct node{

    int s, e, m;
    node *l, *r;
    long long int v;
    int j;

    node(int S, int E, int J){
        s = S;
        e = E;
        m = (s + e)/2;
        j = J;

        if(s == e){
            v = num[s][j];
        }
        else{
            l = new node(s,m,J);
            r = new node(m + 1, e,J);

            v = min(l -> v, r -> v);
        }
    }

    long long int query(int S, int E){
        if(S <= s && e <= E) return v;

        long long int V = 1e18;

        if(S <= m){
            V = min(V , l -> query(S,E));
        }
        if(m < E){
            V = min(V, r -> query(S,E));
        }
        return V;
    }

} *nodes[25];


vector<long long> minimum_costs(vector<int> H, vector<int> L, vector<int> R) {
    N = H.size();
    Q = L.size();

    if(N >= 5001){

        for(int i = 1; i <= N; i++){
            lst[i] = H[i - 1];
        }

        for(int i = 0; i <= N; i++){
            for(int j = 0; j <= 20; j++){
                num[i][j] = 1e18;
            }
        }

        recurse(20,1,N);

        for(int j = 0; j <= 20; j++){
            nodes[j] = new node(1,N,j);
        }

        /*for(int j = 0; j <= 20; j++){
            for(int i = 1 ; i <= N; i++){
                printf("%d ",num[i][j]);
            }
            printf("\n");
        }*/

        build(1,1,N);

        vector<long long int> banna;

        for(int i = 0; i < Q; i++){
            vector<vector<long long int>> v1;

            v1.push_back({0,L[i]+1,R[i]+1,0});

            long long int ans = 1e18;

            long long int cont = 20;
            while(cont >= 0){
                vector<vector<long long int>> temp;
                //printf("%d %d\n",ans,cont);
                while(!v1.empty()){
                    vector<long long int> v = v1.back();
                    v1.pop_back();

                    //printf("%d %d %d %d\n",v[0],v[1],v[2],v[3]);

                    long long int k = ans;

                    pair<int,int> p = query(1,1,N,v[1],v[2]);
                    if(p.first != cont){
                        temp.push_back(v);
                        continue;
                    }

                    if(v[2] == v[1]){
                        ans = min(ans, cont + v[0]);
                        continue;
                    }

                    pair<int,int> p1 = query1(1,1,N,v[1],v[2]);

                    ans = min(ans, p1.first * (v[2] - v[1] + 1));

                    if(v[3] == 0){
                        if(p.second == -p1.second){
                            int it = p.second;
                            if(it != v[1]){
                                temp.push_back({v[0] + cont * (v[2] - it + 1), v[1], it - 1,2});
                            }
                            if(it != v[2]){
                                temp.push_back({v[0] + cont * (it - v[1] + 1), it + 1, v[2],1});
                            }
                        }
                        else{
                            int it = -p1.second;
                            int it1 = p.second;

                            if(it != v[1]){
                                temp.push_back({v[0] + cont * (v[2] - it + 1), v[1], it - 1, 2});
                            }
                            if(it1 != v[2]){
                                temp.push_back({v[0] + cont * (it1 - v[1] + 1), it1 + 1, v[2],1});
                            }
                            ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(it + 1, it1));
                        }
                    }
                    else if(v[3] == 1){
                        if(p.second == -p1.second){
                            int it = p.second;
                            if(it != v[1]){
                                ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(it - 1,it - 1));
                            }
                            if(it != v[2]){
                                temp.push_back({v[0] + cont * (it - v[1] + 1), it + 1, v[2],1});
                            }
                        }
                        else{
                            int it = -p1.second;
                            int it1 = p.second;

                            if(it != v[1]){
                                ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(it - 1,it - 1));
                            }
                            if(it1 != v[2]){
                                temp.push_back({v[0] + cont * (it1 - v[1] + 1), it1 + 1, v[2],1});
                            }
                            ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(it + 1, it1));
                        }
                    }
                    else{
                        if(p.second == -p1.second){
                            int it = p.second;
                            if(it != v[1]){
                                temp.push_back({v[0] + cont * (v[2] - it + 1), v[1], it - 1,2});
                            }
                            if(it != v[2]){
                                ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(v[2],v[2]));
                            }
                        }
                        else{
                            int it = -p1.second;
                            int it1 = p.second;

                            if(it != v[1]){
                                temp.push_back({v[0] + cont * (v[2] - it + 1), v[1], it - 1, 2});
                            }
                            if(it1 != v[2]){
                                ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(v[2],v[2]));
                            }
                            ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(it + 1, it1));
                        }
                    }

                    ans = min(ans + v[0],k);
                }

                v1 = temp;

                cont--;


            }
            banna.push_back(ans);
        }

        return banna;

    }
    else{
        for(int i = 0; i < N; i++){
            lst[i] = H[i];
        }

        build(1,0,N-1);

        vector<long long int> banna;

        for(int i = 0; i < Q; i++){
            int l,r;

            l = L[i];
            r = R[i];

            queue<vector<long long int>> pq;

            pq.push({0,l,r});

            long long int ans = 1e18;

            while(!pq.empty()){
                vector<long long int> v = pq.front();
                pq.pop();

                if(v[1] == v[2]){
                    ans = min(ans, v[0] + lst[v[1]]);
                    continue;
                }

                int it = query(1,0,N-1,v[1],v[2]).second;

                if(it != v[1]){
                    pq.push({lst[it] * (v[2] - it + 1) + v[0], v[1], it - 1 });
                }
            if(it != v[2]){
                pq.push({lst[it] * (it - v[1] + 1) + v[0], it + 1, v[2] });
            }
        }
        banna.push_back(ans);

        }
        return banna;
    }
}

int main() {
  int N;
  int Q;

  scanf(" %d",&N);
  scanf(" %d",&Q);

  std::vector<int> H(N);
  for (int i = 0; i < N; ++i) {
        scanf(" %d",&H[i]);
  }
  std::vector<int> L(Q), R(Q);
  for (int j = 0; j < Q; ++j) {
    scanf(" %d",&L[j]);
  scanf(" %d",&R[j]);
  }

  std::vector<long long> C = minimum_costs(H, L, R);
  for (size_t j = 0; j < C.size(); ++j) {
    printf("%lld\n", C[j]);
  }
  return 0;
}
/*
3 6
2 2 1
0 0
0 1
0 2
1 1
1 2
2 2
*/

Compilation message

meetings.cpp: In function 'long long int recurse(int, int, int)':
meetings.cpp:77:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   77 |     for(int i = 0; i < temp.size() - 1; i++){
      |                    ~~^~~~~~~~~~~~~~~~~
meetings.cpp: In function 'std::pair<int, int> query(int, int, int, int, int)':
meetings.cpp:42:1: warning: control reaches end of non-void function [-Wreturn-type]
   42 | }
      | ^
meetings.cpp: In function 'std::pair<int, int> query1(int, int, int, int, int)':
meetings.cpp:57:1: warning: control reaches end of non-void function [-Wreturn-type]
   57 | }
      | ^
meetings.cpp: In function 'int main()':
meetings.cpp:329:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  329 |   scanf(" %d",&N);
      |   ~~~~~^~~~~~~~~~
meetings.cpp:330:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  330 |   scanf(" %d",&Q);
      |   ~~~~~^~~~~~~~~~
meetings.cpp:334:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  334 |         scanf(" %d",&H[i]);
      |         ~~~~~^~~~~~~~~~~~~
meetings.cpp:338:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  338 |     scanf(" %d",&L[j]);
      |     ~~~~~^~~~~~~~~~~~~
meetings.cpp:339:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  339 |   scanf(" %d",&R[j]);
      |   ~~~~~^~~~~~~~~~~~~
/usr/bin/ld: /tmp/ccc2mtgr.o: in function `main':
grader.cpp:(.text.startup+0x0): multiple definition of `main'; /tmp/ccwEosPs.o:meetings.cpp:(.text.startup+0x0): first defined here
collect2: error: ld returned 1 exit status