Submission #1040719

# Submission time Handle Problem Language Result Execution time Memory
1040719 2024-08-01T08:43:56 Z 1557중연결요소(#11043) Tricks of the Trade (CEOI23_trade) C++17
0 / 100
9 ms 21448 KB
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int INF = 1e18;
int A[250005];
int B[250005];
int C[250005];
int D[250005];
vector<array<int, 2>> V;
int ans = -INF;
int K;
int F[250005];
struct SegTree {
    struct Node {
        int l, r, cnt, sum;
        Node():l(-1),r(-1),cnt(0),sum(0) {}
        Node(int c) : l(-1), r(-1), cnt(1), sum(c) {}
    };
    vector<Node> seg;
    vector<int> root;
    int MAX;
    void init(int N) {
        int i;
        for(i=1;i<N;i*=2) {}
        MAX = i;
        seg.clear();
        root.clear();
        root.push_back(cons(0, MAX));
    }
    int cons(int s, int e) {
        Node c = Node();
        int v = seg.size();
        seg.push_back(c);
        int mid = s + e >> 1;
        //cout << s << ' ' << e << ' ' << v << '\n';
        if(e == s + 1) return v;
        if(s != mid) {
            int l1 = cons(s, mid);
            int r1 = cons(mid, e);
            seg[v].l = l1, seg[v].r = r1;
        }
        //cout << s << ' ' << e << ' ' << v << '\n';
        //cout << seg[v].l <<' ' << seg[v].r << '\n';
        assert(v != -1);
        return v;
    }
    int add(int k, int v, int n, int ns, int ne) {
        Node c = Node();
        int cc= seg[n].cnt + 1;
        int cs= seg[n].sum + v;
        int cl = seg[n].l, cr = seg[n].r;
        c.cnt = cc, c.sum = cs, c.l = cl, c.r = cr;
        //cout << k << ' ' << v << ' ' << n << ' ' << ns << ' ' << ne << '\n';
        int num = seg.size();
        seg.push_back(c);
        if(ns+1==ne) {
            return num;
        }
        int mid = ns + ne >> 1;
        if(mid <= k) {
            int v1 = add(k, v, seg[n].r, mid, ne);
            seg[num].r = v1;
            return num;
        }
        else {
            int v1 = add(k, v, seg[n].l, ns, mid);
            seg[num].l = v1;
            return num;
        }
    }
    int add_node(int k, int v) {
        //cout << "ADD:" << k << ' ' << v << '\n';
        root.push_back(add(k, v, root.back(), 0, MAX));
    }
    int get_val(int n1, int n2, int ns, int ne, int k) {
        //cout << n1 << ' ' << n2 <<' ' << ns << ' ' << ne << ' ' << k << '\n';
        if(k==0) return 0;
        if(ns+1==ne) return seg[n1].sum - seg[n2].sum;
        int r1 = seg[n1].r, r2 = seg[n2].r;
        assert(r1 != -1 && r2 != -1);
        int v = seg[r1].cnt - seg[r2].cnt;
        if(v==k) {
            int res = seg[r1].sum - seg[r2].sum;
            //cout << n1 << ' ' << n2 << ' ' << res << '\n';
            return res;
        }
        int mid = ns + ne >> 1;
        if(v < k) {
            int res = seg[r1].sum - seg[r2].sum + get_val(seg[n1].l, seg[n2].l, ns, mid, k-v);
            //cout << n1 << ' ' << n2 << ' ' << res << '\n';
            return res;
        }
        int res = get_val(r1, r2, mid, ne, k);
        //cout << n1 << ' ' << n2 << ' ' << res << '\n';
        return res;
    }
    int get_calc(int s, int e, int k) {
        int res = get_val(root[e+1], root[s], 0, MAX, k);
        //cout << s+1 << ' ' << e+1 << " : " << res << '\n';
        return res;
    }
};
SegTree tree;
int G[250005];
void tree_cons(int N) {
    int i, j;
    tree.init(N+3);
    /*cout << "init done\n";
    for(i=0;i<tree.seg.size();i++) {
        cout << i << " : " << tree.seg[i].l <<' ' << tree.seg[i].r << ' ' << tree.seg[i].cnt <<' ' << tree.seg[i].sum << '\n';
    }
    for(i=0;i<tree.root.size();i++) cout <<tree.root[i] << ' ';
    cout << '\n';*/
    vector<array<int, 2>> V2;
    for(i=0;i<N;i++) V2.push_back({B[i], i});
    sort(V2.begin(),V2.end());
    for(i=0;i<N;i++) G[V2[i][1]] = i;
    for(i=0;i<N;i++) tree.add_node(G[i], B[i]);
    /*for(i=0;i<tree.seg.size();i++) {
        cout << i << " : " << tree.seg[i].l <<' ' << tree.seg[i].r << ' ' << tree.seg[i].cnt <<' ' << tree.seg[i].sum << '\n';
    }
    for(i=0;i<tree.root.size();i++) cout <<tree.root[i] << ' ';
    cout << '\n';*/
}
int calc_val(int s, int e) {
    int res = tree.get_calc(s, e, K) - (F[e] - (s-1>=0?F[s-1]:0));
    //cout << s+1 <<' ' << e+1 << " : " << res <<'\n';
    return res;
}
void calc(int s, int e) {
    int i, j;
    int ma = -INF, id = -1;
    priority_queue<int, vector<int>, greater<int>> PQ;
    int sum = 0;
    for(i=s;i<=e;i++) {
        sum -= A[i];
        bool isok = false;
        if(PQ.size() == K-1) isok = true;
        if(PQ.size() == K && PQ.top() <= B[i]) isok = true;
        PQ.push(B[i]);
        sum += B[i];
        if(PQ.size() > K) {
            sum -= PQ.top();
            PQ.pop();
        }
        if(PQ.size() < K) continue;
        if(sum > ma) {
            ma = sum;
            id = i;
        }
        if(sum > ans) {
            ans = sum;
            V.clear();
        }
        if(ans == sum && isok) {
            V.push_back({s, i});
        }
    }
}
void DnC(int s, int e, int a, int b) {
    if(s>e) return;
    int i, j;
    a = max(a, s+K-1);
    int mid = s + e >> 1;
    int ma = -INF, id = b;
    //cout <<"DNC: " << s << ' ' << e << ' ' << a << ' ' << b << '\n';
    for(i=max(mid+K-1, a); i <= b; i++) {
        int v = calc_val(mid, i);
        if(v > ma) {
            ma = v;
            id = i;
        }
    }
    C[mid] = ma, D[mid] = id;
    if(ma > ans) ans = ma;
    DnC(s, mid-1, a, id);
    DnC(mid+1, e, id, b);
}
int E[250005];
signed main() {
    cin.sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int N;
    cin >> N >> K;
    int i, j;
    for(i=0;i<N;i++) cin >> A[i];
    for(i=0;i<N;i++) F[i] = A[i];
    for(i=1;i<N;i++) F[i] += F[i-1];
    for(i=0;i<N;i++) cin >> B[i];
    tree_cons(N);
    DnC(0, N-1, 0, N-1);
    vector<int> pos;
    for(i=0;i<N;i++) {
        if(C[i]==ans) pos.push_back(i);
    }
    pos.push_back(N);
    //cout << ans << '\n';
    for(int i=0;i<pos.size();i++) {
        int n = pos[i];
        if(n==N) continue;
        V.push_back({n, D[n]});
        if(D[n]+1<pos[i+1]) {
            calc(pos[i], pos[i+1]-1);
        }
    }
    vector<vector<array<int, 2>>> in, out;
    in.resize(N);
    out.resize(N);
    int cnt = 0;
    for(auto k : V) {
        //k[0] ~ k[1]
        // kth element <= a[i] -> ?
        int v = (ans + F[k[1]] - (k[0]-1>=0?F[k[0]-1]:0)) - tree.get_calc(k[0], k[1], K-1);
        in[k[0]].push_back({v, cnt});
        out[k[1]].push_back({v, cnt});
        cnt++;
    }
    /*for(i=0;i<N;i++) cout << D[i] <<' ';
    cout << '\n';
    for(auto k : V) cout << k[0]+1 << ' ' << k[1]+1 << '\n';*/
    cout << ans <<'\n';
    set<array<int, 2>> S;
    for(i=0;i<N;i++) {
        for(auto n : in[i]) {
            S.insert(n);
        }
        if(!S.empty() && B[i] >= (*S.begin())[0]) cout << "1";
        else cout << "0";
        for(auto n : out[i]) {
            S.erase(n);
        }
    }
}

Compilation message

trade.cpp: In member function 'long long int SegTree::cons(long long int, long long int)':
trade.cpp:34:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   34 |         int mid = s + e >> 1;
      |                   ~~^~~
trade.cpp: In member function 'long long int SegTree::add(long long int, long long int, long long int, long long int, long long int)':
trade.cpp:59:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   59 |         int mid = ns + ne >> 1;
      |                   ~~~^~~~
trade.cpp: In member function 'long long int SegTree::add_node(long long int, long long int)':
trade.cpp:74:5: warning: no return statement in function returning non-void [-Wreturn-type]
   74 |     }
      |     ^
trade.cpp: In member function 'long long int SegTree::get_val(long long int, long long int, long long int, long long int, long long int)':
trade.cpp:87:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   87 |         int mid = ns + ne >> 1;
      |                   ~~~^~~~
trade.cpp: In function 'void tree_cons(long long int)':
trade.cpp:106:12: warning: unused variable 'j' [-Wunused-variable]
  106 |     int i, j;
      |            ^
trade.cpp: In function 'void calc(long long int, long long int)':
trade.cpp:138:22: warning: comparison of integer expressions of different signedness: 'std::priority_queue<long long int, std::vector<long long int>, std::greater<long long int> >::size_type' {aka 'long unsigned int'} and 'long long int' [-Wsign-compare]
  138 |         if(PQ.size() == K-1) isok = true;
      |            ~~~~~~~~~~^~~~~~
trade.cpp:139:22: warning: comparison of integer expressions of different signedness: 'std::priority_queue<long long int, std::vector<long long int>, std::greater<long long int> >::size_type' {aka 'long unsigned int'} and 'long long int' [-Wsign-compare]
  139 |         if(PQ.size() == K && PQ.top() <= B[i]) isok = true;
      |            ~~~~~~~~~~^~~~
trade.cpp:142:22: warning: comparison of integer expressions of different signedness: 'std::priority_queue<long long int, std::vector<long long int>, std::greater<long long int> >::size_type' {aka 'long unsigned int'} and 'long long int' [-Wsign-compare]
  142 |         if(PQ.size() > K) {
      |            ~~~~~~~~~~^~~
trade.cpp:146:22: warning: comparison of integer expressions of different signedness: 'std::priority_queue<long long int, std::vector<long long int>, std::greater<long long int> >::size_type' {aka 'long unsigned int'} and 'long long int' [-Wsign-compare]
  146 |         if(PQ.size() < K) continue;
      |            ~~~~~~~~~~^~~
trade.cpp:131:12: warning: unused variable 'j' [-Wunused-variable]
  131 |     int i, j;
      |            ^
trade.cpp:132:20: warning: variable 'id' set but not used [-Wunused-but-set-variable]
  132 |     int ma = -INF, id = -1;
      |                    ^~
trade.cpp: In function 'void DnC(long long int, long long int, long long int, long long int)':
trade.cpp:164:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  164 |     int mid = s + e >> 1;
      |               ~~^~~
trade.cpp:162:12: warning: unused variable 'j' [-Wunused-variable]
  162 |     int i, j;
      |            ^
trade.cpp: In function 'int main()':
trade.cpp:199:18: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  199 |     for(int i=0;i<pos.size();i++) {
      |                 ~^~~~~~~~~~~
trade.cpp:186:12: warning: unused variable 'j' [-Wunused-variable]
  186 |     int i, j;
      |            ^
# Verdict Execution time Memory Grader output
1 Runtime error 8 ms 21448 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Runtime error 9 ms 21340 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Runtime error 9 ms 21340 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Runtime error 8 ms 21340 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Runtime error 8 ms 21340 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Runtime error 8 ms 21448 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -