Submission #699019

# Submission time Handle Problem Language Result Execution time Memory
699019 2023-02-15T10:35:26 Z Cross_Ratio Inspector (POI13_ins) C++14
92 / 100
5000 ms 6752 KB
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
int N, M;
int L[100005];
int R[100005];
int val[100005];
array<int, 3> A[100005];
struct SegTree {
    struct Node {
        int mi, p;
        Node():mi(0), p(0) {}
        Node(int _m, int _p) : mi(_m), p(_p) {}
    };
    vector<Node> seg;
    int MAX;
    SegTree(int N) {
        int i;
        for(i=1;i<2*N;i*=2) {}
        seg.resize(i);
        MAX = i;
    }
    void cons() {
        for(int i = MAX/2-1;i>=1;i--) {
            seg[i].mi = min(seg[2*i].mi, seg[2*i+1].mi);
        }
    }
    void prop(int n, int ns, int ne) {
        if(seg[n].p) {
            seg[n].mi += seg[n].p;
            if(n < MAX/2) {
                seg[2*n].p += seg[n].p;
                seg[2*n+1].p += seg[n].p;
            }
            seg[n].p = 0;
        }
    }
    void add(int s, int e, int k, int n, int ns, int ne) {
        prop(n,ns,ne);
        if(e<=ns||ne<=s) return;
        if(s<=ns&&ne<=e) {
            seg[n].p += k;
            prop(n,ns,ne);
            return;
        }
        int mid = ns + ne >> 1;
        add(s, e, k, 2*n, ns, mid);
        add(s, e, k, 2*n+1, mid, ne);
        if(n<MAX/2) seg[n].mi = min(seg[2*n].mi, seg[2*n+1].mi);
    }
    int sum(int s, int e, int n, int ns, int ne) {
        prop(n,ns,ne);
        if(e<=ns||ne<=s) return INF;
        if(s<=ns&&ne<=e) return seg[n].mi;
        int mid = ns + ne >> 1;
        return min(sum(s, e, 2*n, ns, mid), sum(s, e, 2*n+1, mid, ne));
    }
};
bool isPos(int c) {
    //cout << "isPos " << c << '\n';
    int i, j;
    for(i=0;i<M;i++) val[i] = -1;
    for(i=0;i<N;i++) L[i] = M, R[i] = -1;
    for(i=0;i<c;i++) {
        if(val[A[i][0]]==-1) val[A[i][0]] = A[i][2];
        else if(val[A[i][0]] != A[i][2]) return false;
        L[A[i][1]] = min(L[A[i][1]], A[i][0]);
        R[A[i][1]] = max(R[A[i][1]], A[i][0]);
    }
    //cout << "step 1\n";
    priority_queue<array<int, 2>, vector<array<int, 2>>, greater<array<int, 2>>> PQ1, PQ2;
    int free = 0;
    for(i=0;i<N;i++) {
        if(R[i]==-1) free++;
        else PQ1.push({L[i], i});
    }
    /*for(i=0;i<M;i++) {
        cout << val[i] << ' ';
    }
    cout << '\n';*/
    int m = 0;
    int must = 0;
    SegTree tree(M+3);
    int MAX = tree.MAX;
    for(i=0;i<M;i++) {
        int v = (val[i] == -1 ? INF : val[i]);
        tree.seg[i+MAX/2].mi = v;
    }
    tree.cons();
    for(i=0;i<N;i++) {
        if(R[i]!=-1) {
            tree.add(L[i], R[i]+1, -1, 1, 0, MAX/2);
        }
    }
    for(i=0;i<M;i++) {
        //cout << i << " : " << val[i] << '\n';
        if(val[i] == -1) continue;
        while(!PQ1.empty() && PQ1.top()[0] <= i) {
            auto k = PQ1.top();
            PQ1.pop();
            PQ2.push({R[k[1]], k[1]});
            must++;
            m++;
        }
        //cout << m << ' ' << must << ' ' << free << '\n';
        if(m >= val[i]) {
            m = min(m, val[i]);
            if(m < must) return false;
        }
        else {
            while(!PQ1.empty() && m < val[i]) {
                auto k = PQ1.top();
                int id = k[1];
                int v = tree.sum(i, L[id], 1, 0, MAX/2);
                if(v <= 0) break;
                else {
                    PQ1.pop();
                    PQ2.push({R[id], id});
                    tree.add(i, L[id], -1, 1, 0, MAX/2);
                    must++;
                    m++;
                }
            }
            if(m < val[i]) {
                free -= val[i] - m;
                m = val[i];
                if(free < 0) return false;
            }
        }
        while(!PQ2.empty() && PQ2.top()[0] <= i) {
            PQ2.pop();
            must--;
        }
    }
    return true;
}
void solve() {
    cin >> N >> M;
    int i, j;
    for(i=0;i<M;i++) {
        int a, b, c;
        cin >> a >> b >> c;
        a--, b--;
        A[i] = {a, b, c+1};
    }
    int s = 0, e = M;
    while(s+1<e) {
        int mid = (s+e)/2;
        if(isPos(mid+1)) s = mid;
        else e = mid;
    }
    cout << s+1 << '\n';
}
signed main() {
    cin.sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--) {
        solve();
    }
}

Compilation message

ins.cpp: In member function 'void SegTree::add(int, int, int, int, int, int)':
ins.cpp:46:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   46 |         int mid = ns + ne >> 1;
      |                   ~~~^~~~
ins.cpp: In member function 'int SegTree::sum(int, int, int, int, int)':
ins.cpp:55:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   55 |         int mid = ns + ne >> 1;
      |                   ~~~^~~~
ins.cpp: In function 'bool isPos(int)':
ins.cpp:61:12: warning: unused variable 'j' [-Wunused-variable]
   61 |     int i, j;
      |            ^
ins.cpp: In function 'void solve()':
ins.cpp:139:12: warning: unused variable 'j' [-Wunused-variable]
  139 |     int i, j;
      |            ^
# Verdict Execution time Memory Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Correct 2 ms 340 KB Output is correct
5 Correct 14 ms 340 KB Output is correct
6 Correct 34 ms 340 KB Output is correct
7 Correct 55 ms 444 KB Output is correct
8 Correct 431 ms 1068 KB Output is correct
9 Correct 897 ms 1800 KB Output is correct
10 Correct 2364 ms 3344 KB Output is correct
11 Correct 2453 ms 3092 KB Output is correct
12 Execution timed out 5062 ms 6752 KB Time limit exceeded
13 Correct 4796 ms 6752 KB Output is correct