Submission #952702

# Submission time Handle Problem Language Result Execution time Memory
952702 2024-03-24T15:29:07 Z CLC__Haaland Fortune Telling 2 (JOI14_fortune_telling2) C++17
0 / 100
4 ms 13912 KB
#include <bits/stdc++.h>
#define se          second
#define fs          first
#define pb          push_back
#define ll          long long
#define ii          pair<ll,ll>
#define ld          long double
#define SZ(v)       (int)v.size()
#define ALL(v)      v.begin(), v.end()
#define bit(msk, i) ((msk >> i) & 1)
#define iter(id, v) for (auto id : v)
#define rep(i,m,n)  for(int i=(m); i<=(n); i++)
#define reb(i,m,n)  for(int i=(m); i>=(n); i--)

using namespace std;

mt19937_64 rd(chrono :: steady_clock :: now().time_since_epoch().count());
ll Rand(ll l, ll r) { return uniform_int_distribution<ll> (l, r)(rd); }


const int N = 2e5 + 7;
const int Mod = 1e9 + 7;
const int szBL = 500;
const int INF = 2e9 + 7;
const int BASE = 137;

struct Arr_Data {
    int a, b;
    bool isswapped;
    Arr_Data () : a(0), b(0), isswapped(0) {};
};

///input:
int n, Q;
Arr_Data arr[N];
int qr[N];

///compress:
int num_Val;
vector<int> nen;

int CPR (int X) {
    return lower_bound(ALL(nen), X) - nen.begin() + 1;
}

void compress () {
    sort (ALL(nen));
    nen.resize(num_Val = unique(ALL(nen)) - nen.begin());
    rep (i, 1, n) {
        arr[i].a = CPR(arr[i].a);
        arr[i].b = CPR(arr[i].b);
    }
    rep (i, 1, Q) qr[i] = CPR(qr[i]);
}

///data:
vector<vector<int>> queries, events;

namespace sub3 {
    struct Segment_Tree_helper1 {
        int Range;
        int st[N << 2], st2[N << 2];
        void init(int n ) {
            Range = n;
            rep (i, 1, Range << 2) st[i] = 0, st2[i] = 0;
        }
        void update (int id, int l, int r, int pos, int val) {
            if (l > pos || r < pos) return;
            if (l == r) {
                st[id] = val;
                return;
            }
            int mid = l + r >> 1;
            update (id << 1, l, mid, pos, val);
            update (id << 1 | 1, mid + 1, r, pos, val);
            st[id] = max(st[id << 1], st[id << 1 | 1]);
        }
        void Add (int id, int l, int r, int pos, int val) {
            if (l > pos || r < pos) return;
            if (l == r) {
                st2[id] += val;
                return;
            }
            int mid = l + r >> 1;
            Add (id << 1, l, mid, pos, val);
            Add (id << 1 | 1, mid + 1, r, pos, val);
            st2[id] = st2[id << 1] + st2[id << 1 | 1];
        }
        int get (int id, int l, int r, int u, int v) {
            if (l > v || r < u) return 0;
            if (l >= u && r <= v) return st[id];
            int mid = l + r >> 1;
            return max(get (id << 1, l, mid, u, v), get (id << 1 | 1, mid + 1, r, u, v));
        }
        int Sum (int id, int l, int r, int u, int v) {
            if (l > v || r < u) return 0;
            if (l >= u && r <= v) return st2[id];
            int mid = l + r >> 1;
            return Sum (id << 1, l, mid, u, v) + Sum (id << 1 | 1, mid + 1, r, u, v);
        }
        int walk_Left (int id, int l, int r, int bound) { ///walk to Find L when the upper_bound is bound
            if (l > bound) return -1;
            if (st[id] == 0) return -1;
            if (l == r) return l;
            int mid = l + r >> 1;
            int res = -1;
            if (mid + 1 <= bound) res = walk_Left (id << 1 | 1 , mid + 1, r, bound);
            if (res == -1) res = walk_Left (id << 1, l, mid, bound);
            return res;
        }
        int walk_Right (int id, int l, int r, int bound) {  ///walk to Find R when the lower_bound is bound
            if (r < bound) return -1;
            if (st[id] == 0) return -1;
            if (l == r) return l;
            int mid = l + r >> 1;
            int res = -1;
            if (mid >= bound) res = walk_Right (id << 1, l, mid, bound);
            if (res == -1) res = walk_Right (id << 1 | 1, mid + 1, r, bound);
            return res;
        }

        void update (int pos, int val) {
            update (1, 1, Range, pos, val);
        }
        void Add (int pos, int val) {
            Add (1, 1, Range, pos, val);
        }
        int get (int L, int R) {
            return get (1, 1, Range, L, R);
        }
        int Sum (int L, int R) {
            return Sum (1, 1, Range, L, R);
        }
        int walk_Left (int bound){
            return walk_Left (1, 1, Range, bound);
        }
        int walk_Right (int bound) {
            return walk_Right (1, 1, Range, bound);
        }

    }ST, Partition, values_Range;

    void solution() {
        nen = {0, INF};
        rep (i, 1, n) nen.push_back(arr[i].a), nen.push_back(arr[i].b);
        rep (i, 1, Q) nen.push_back(qr[i]);

        compress();

        events.resize(num_Val + 1, vector<int> (0));
        queries.resize(num_Val + 1, vector<int> (0));
        rep (i, 1, n) {
            if (arr[i].a > arr[i].b) {
                swap(arr[i].a, arr[i].b);
                arr[i].isswapped = 1;
            }
            events[arr[i].b].push_back(i);
        }
        rep (i, 1, Q) queries[qr[i]].push_back(i);

        ST.init(Q), Partition.init(Q);
        rep (i, 1, Q) ST.update(i, qr[i]);

        values_Range.init(num_Val);
        values_Range.Add(ST.get(1, num_Val - 1), 1); ///set stored maximum value of each range
        vector<int> final_arr(n + 1, 0);
        reb (X, num_Val, 1) {
            iter (&id, queries[X]) {
                int boundL = Partition.walk_Left(id - 1), boundR = Partition.walk_Right(id + 1);
                if (boundL == -1) boundL = 0;
                if (boundR == -1) boundR = Q + 1;
                Partition.update (id, 1);
                Partition.Add (id, 1);
                values_Range.Add (ST.get(boundL + 1, boundR - 1), -1);
//                cout << "183: Update: "<<X<<" "<<id<<" "<<boundL<<" "<<boundR<<"\n";
                if (boundL <= id - 1) values_Range.Add (ST.get(boundL + 1, id - 1), 1);
                if (id + 1 <= boundR) values_Range.Add (ST.get(id + 1, boundR - 1), 1);
            }
            iter (&id, events[X]) {
                int A = arr[id].a, B = arr[id].b, swapped = arr[id].isswapped;
                int parity = Partition.Sum (1, Q) + values_Range.Sum (arr[id].a, arr[id].b - 1);
                if (swapped) {
                    int smallest_idx = Partition.walk_Right(1);
                    if (smallest_idx == -1) smallest_idx = Q + 1;
//                    cout << "199: "<<id<<":"<<smallest_idx<<" "<<parity<<"\n";
                    if (ST.get(1, smallest_idx - 1) >= A) --parity;
                    swap(A, B);
                }
//                cout << id<< " "<<parity <<" "<<Partition.get(1, Q)<<"+"<<values_Range.get(arr[id].a, arr[id].b - 1)<<"\n";
                if (parity % 2 == 1) final_arr[id] = B;
                else final_arr[id] = A;
            }
        }
        ll res = 0;
        rep (i, 1, n) {
//            cout << nen[final_arr[i] - 1] << " ";
            res += nen[final_arr[i] - 1];
        }
        cout << res <<"\n";
    }
}
void solution() {
    cin >> n >> Q;
    rep (i, 1, n) {
        cin >> arr[i].a >> arr[i].b;
    }
    rep (i, 1, Q) cin >> qr[i];
//    if (n <= 4000) sub2 :: solution();
//    else
        sub3 :: solution();
}

#define file(name) freopen(name".inp", "r", stdin); freopen(name".out", "w", stdout);

int main() {
//    file("c");
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    ll num_Test = 1;
//    cin >> num_Test;
    while(num_Test--)
        solution();
}
/*
4 4
aaab
1 4
1 3
3 4
2 4


*/

Compilation message

fortune_telling2.cpp: In member function 'void sub3::Segment_Tree_helper1::update(int, int, int, int, int)':
fortune_telling2.cpp:73:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   73 |             int mid = l + r >> 1;
      |                       ~~^~~
fortune_telling2.cpp: In member function 'void sub3::Segment_Tree_helper1::Add(int, int, int, int, int)':
fortune_telling2.cpp:84:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   84 |             int mid = l + r >> 1;
      |                       ~~^~~
fortune_telling2.cpp: In member function 'int sub3::Segment_Tree_helper1::get(int, int, int, int, int)':
fortune_telling2.cpp:92:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   92 |             int mid = l + r >> 1;
      |                       ~~^~~
fortune_telling2.cpp: In member function 'int sub3::Segment_Tree_helper1::Sum(int, int, int, int, int)':
fortune_telling2.cpp:98:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   98 |             int mid = l + r >> 1;
      |                       ~~^~~
fortune_telling2.cpp: In member function 'int sub3::Segment_Tree_helper1::walk_Left(int, int, int, int)':
fortune_telling2.cpp:105:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  105 |             int mid = l + r >> 1;
      |                       ~~^~~
fortune_telling2.cpp: In member function 'int sub3::Segment_Tree_helper1::walk_Right(int, int, int, int)':
fortune_telling2.cpp:115:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  115 |             int mid = l + r >> 1;
      |                       ~~^~~
# Verdict Execution time Memory Grader output
1 Incorrect 4 ms 13912 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 4 ms 13912 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 4 ms 13912 KB Output isn't correct
2 Halted 0 ms 0 KB -