Submission #830627

#TimeUsernameProblemLanguageResultExecution timeMemory
830627JohannAlternating Current (BOI18_alternating)C++14
100 / 100
108 ms9900 KiB
#include <bits/stdc++.h>
using namespace std;

#define pii pair<int,int>
#define vi vector<int>
#define vb vector<bool>
#define all(x) (x).begin(), (x).end()
#define sz(x) (int) (x).size()

struct wire {
    int a, b, idx;
};

struct item {
    int d1, d2;
    int f2f1, f2f2;
};
const item NEUTRAL = { 0, 0, INT_MAX, INT_MAX };
struct SegTree {
    vector<item> arr;
    int size;
    void update(item & self, item & c1, item & c2) {
        if (self.d1 > 0) self.f2f1 = INT_MAX;
        else if (c1.f2f1 != INT_MAX) self.f2f1 = c1.f2f1;
        else self.f2f1 = c2.f2f1;
        if (self.d2 > 0) self.f2f2 = INT_MAX;
        else if (c1.f2f2 != INT_MAX) self.f2f2 = c1.f2f2;
        else self.f2f2 = c2.f2f2;
    }
    void update(item & self, int pos) {
        self.f2f1 = (self.d1 > 0) ? INT_MAX : pos;
        self.f2f2 = (self.d2 > 0) ? INT_MAX : pos;
    }
    void init(int _n) {
        size = 1;
        while (size < _n) size *= 2;
        arr.assign(2 * size, { 0, 0, INT_MAX, INT_MAX });
        for (int i = 0; i < size; ++i) {
            arr[size + i] = { 0 , 0, i, i };
        }
        for (int x = size-1; x > 0; --x) update(arr[x], arr[2 * x], arr[2 * x + 1]);
    }
    item query(int a, int b) {
        if (a < b) {
            return query(a, b, 1, 0, size);
        } else {
            item ans = { 0, 0, INT_MAX, INT_MAX };
            item c1 = query(a, size, 1, 0, size);
            item c2 = query(0, b, 1, 0, size);
            if (c2.f2f1 != INT_MAX) c2.f2f1 += size;
            if (c2.f2f2 != INT_MAX) c2.f2f2 += size;
            update(ans, c1, c2);
            return ans;
        }
    }
    item query(int a, int b, int x, int lx, int rx) {
        if (a <= lx && rx <= b) { return arr[x] = arr[x]; }
        if (b <= lx || rx <= a) { return NEUTRAL; }
        int m = (lx + rx) / 2;
        item ans = { arr[x].d1, arr[x].d2, INT_MAX, INT_MAX };
        item c1 = query(a, b, 2 * x, lx, m);
        item c2 = query(a, b, 2 * x + 1, m, rx);
        update(ans, c1, c2);
        return ans;
    }
    void set(int a, int b, int c) {
        // current \in { +- 1, +- 2 }
        if (a < b) {
            set(a, b, c, 1, 0, size);
        } else {
            set(a, size, c, 1, 0, size);
            set(0, b, c, 1, 0, size);
        }
    }
    void set(int a, int b, int c, int x, int lx, int rx) {
        if (a <= lx && rx <= b) {
            if (abs(c) == 1) { arr[x].d1 += c; }
            else { arr[x].d2 += c / 2; }
            if (rx - lx > 1) update(arr[x], arr[2 * x], arr[2 * x + 1]);
            else update(arr[x], lx);
            return;
        }
        if (b <= lx || rx <= a) { return; }
        int m = (lx + rx) / 2;
        set(a, b, c, 2 * x, lx, m);
        set(a, b, c, 2*x+1, m, rx);
        update(arr[x], arr[2 * x], arr[2 * x + 1]);
    }
};


bool in(wire a, wire b, int N) { // ist a in b?
    int ea = a.b;
    if (a.b <= a.a) ea += N;
    int eb = b.b;
    if (b.b <= b.a) eb += N;
    return (b.a <= a.a && ea <= eb) || (b.a <= a.a + N && ea + N <= eb);
}

int alter(int state) {
    if (abs(state) == 1) return state * 2;
    else return state / 2;
}
void setSeg(SegTree & seg, wire & parent, vector<wire> & children, vi & states, int state) {
    states[parent.idx] = state;
    seg.set(parent.a, parent.b, state);
    state = alter(state);
    for (wire c : children) {
        states[c.idx] = state;
        seg.set(c.a, c.b, state);
    }
}
void coutStates(vi & states) {
    for (int b : states) printf("%d", b-1);
    cout << endl;
}
void alter(SegTree & seg, wire & parent, vector<wire> & children, vi & states) {
    int oldState = states[parent.idx];
    setSeg(seg, parent, children, states, -oldState);
    setSeg(seg, parent, children, states, alter(oldState));
}
void DebugOutput(SegTree & seg, vi & states, int N) {
    for (int j = 0; j < N; ++j) {
        item tmp = seg.query(j, j + 1);
        cout << ((tmp.f2f1 == INT_MAX) ? "-" : to_string(tmp.f2f1));
        cout << "/" << ((tmp.f2f2 == INT_MAX) ? "-" : to_string(tmp.f2f2));
        cout << " ";
    } cout << endl;
    coutStates(states);
    cout << endl;
}


int main() {

    int N, M;
    scanf("%d %d", &N, &M);
    vector<wire> wires(M);
    vi states(M, 0);
    for (int i = 0,a,b; i < M; ++i) {
        scanf("%d %d", &a, &b);
        wires[i] = { --a, b, i };
    }
    sort(wires.begin(), wires.end(), [&](wire & one, wire & two) {
        if (one.a != two.a) return one.a < two.a;
        else {
            int l1 = one.b - one.a; if (l1 <= 0) l1 += N;
            int l2 = two.b - two.a; if (l2 <= 0) l2 += N;
            return l1 > l2;
        }
    });

    // nasty fehler bei 1 N, 1 N ?
    vector<wire> parents;
    vector<vector<wire>> children;
    parents.push_back(wires[0]);
    children.push_back(vector<wire>());
    for (int i = 1; i < M; ++i) {
        if (in(wires[i], parents.back(), N)) {
            children.back().push_back(wires[i]);
        } else {
            parents.push_back(wires[i]);
            children.push_back(vector<wire>());
        }
    }
    reverse(all(parents));
    reverse(all(children));
    while (parents.size() > 1) {
        if (in(parents.back(), parents.front(), N)) {
            children[0].push_back(parents.back());
            for (wire w : children.back()) children[0].push_back(w);
            parents.pop_back();
            children.pop_back();
        } else {
            break;
        }
    }
    reverse(all(parents));
    reverse(all(children));

    SegTree seg;
    seg.init(N);
    for (int i = 0, s; i < sz(parents); ++i) {
        s = (i % 2) + 1;
        setSeg(seg, parents[i], children[i], states, s);
        // DebugOutput(seg, states, N);
    }
    for (int i = 0; i < sz(parents); ++i) {
        item res = seg.query(0, N);
        if (res.f2f1 == INT_MAX && res.f2f2 == INT_MAX) {
            coutStates(states);
            return 0;
        }
        alter(seg, parents[i], children[i], states);
        // DebugOutput(seg, states, N);
    }
    printf("impossible");

}

Compilation message (stderr)

alternating.cpp: In function 'int main()':
alternating.cpp:137:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  137 |     scanf("%d %d", &N, &M);
      |     ~~~~~^~~~~~~~~~~~~~~~~
alternating.cpp:141:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  141 |         scanf("%d %d", &a, &b);
      |         ~~~~~^~~~~~~~~~~~~~~~~
#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...