This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#include "werewolf.h"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define MASK(i) (1ULL << (i))
#define GETBIT(mask, i) (((mask) >> (i)) & 1)
#define ALL(v) (v).begin(), (v).end()
ll max(ll a, ll b){return (a > b) ? a : b;}
ll min(ll a, ll b){return (a < b) ? a : b;}
ll LASTBIT(ll mask){return (mask) & (-mask);}
int pop_cnt(ll mask){return __builtin_popcountll(mask);}
int ctz(ull mask){return __builtin_ctzll(mask);}
int logOf(ull mask){return 63 - __builtin_clzll(mask);}
mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);}
template <class T1, class T2>
bool maximize(T1 &a, T2 b){
if (a < b) {a = b; return true;}
return false;
}
template <class T1, class T2>
bool minimize(T1 &a, T2 b){
if (a > b) {a = b; return true;}
return false;
}
template <class T>
void printArr(T container, string separator = " ", string finish = "\n", ostream &out = cout){
for(auto item: container) out << item << separator;
out << finish;
}
template <class T>
void remove_dup(vector<T> &a){
sort(ALL(a));
a.resize(unique(ALL(a)) - a.begin());
}
struct DSU{
int n;
vector<int> parent, sz;
vector<vector<pair<int, int>>> chain;
DSU(int _n){
n = _n;
parent.resize(n); sz.resize(n, 1);
chain.resize(n);
for(int i = 0; i<n; ++i){
parent[i] = i;
chain[i].push_back({i, -1});
}
}
int find_set(int u){return (u == parent[u]) ? u : (parent[u] = find_set(parent[u]));}
bool same_set(int u, int v){return find_set(u) != find_set(v);}
bool join_set(int u, int v, int w = -1){
u = find_set(u), v = find_set(v);
if (u != v){
if (sz[u] < sz[v]) swap(u, v);
parent[v] = u;
sz[u] += sz[v];
chain[u].back().second = w;
for(pair<int, int> i: chain[v]){
chain[u].push_back(i);
}
chain[v].clear();
return true;
}
return false;
}
vector<pair<int, int>> get_chain(){
return chain[find_set(0)];
}
};
struct FenwickTree{
int n;
vector<int> a;
FenwickTree(int _n){
n = _n;
a.resize(n+1);
}
void update(int i, int w){
while(i <= n){
a[i] += w;
i += LASTBIT(i);
}
}
int get(int i){
int ans = 0;
while(i > 0){
ans += a[i];
i -= LASTBIT(i);
}
return ans;
}
int get(int l, int r){return get(r) - get(l-1);}
};
const int N = 2e5 + 69, LOG_N = 18, INF = 1e9 + 69;
int n, m, q;
int chain1[N], chain2[N];
int pos1[N], pos2[N];
int w1[LOG_N][N], w2[LOG_N][N];
int min_w(int l, int r){
if (l > r) swap(l, r);
if (l == r) return INF;
r--;
int j = logOf(r - l + 1);
return min(w1[j][l], w1[j][r - MASK(j) + 1]);
}
int max_w(int l, int r){
if (l > r) swap(l, r);
if (l == r) return -INF;
r--;
int j = logOf(r - l + 1);
return max(w2[j][l], w2[j][r - MASK(j) + 1]);
}
pair<int, int> spread_min(int p, int cap){
pair<int, int> ans = {p, p};
int l = 0, r = p;
while(l < r){
int mid = (l + r) >> 1;
if (min_w(mid, p) >= cap) r = mid;
else l = mid + 1;
}
ans.first = l;
l = p, r = n-1;
while(l < r){
int mid = (l + r + 1) >> 1;
if (min_w(p, mid) >= cap) l = mid;
else r = mid - 1;
}
ans.second = l;
return ans;
}
pair<int, int> spread_max(int p, int cap){
pair<int, int> ans = {p, p};
int l = 0, r = p;
while(l < r){
int mid = (l + r) >> 1;
if (max_w(mid, p) <= cap) r = mid;
else l = mid + 1;
}
ans.first = l;
l = p, r = n-1;
while(l < r){
int mid = (l + r + 1) >> 1;
if (max_w(mid, p) <= cap) l = mid;
else r = mid - 1;
}
ans.second = l;
return ans;
}
int query[N];
vector<array<int, 3>> createQuery[N], destroyQuery[N];
vector<int> check_validity(int _n, vector<int> X, vector<int> Y,
vector<int> S, vector<int> E,
vector<int> L, vector<int> R) {
n = _n, m = X.size();
q = S.size();
vector<int> ans(q);
// build tree line for minimum node
vector<array<int, 3>> min_edge(m);
for(int i = 0; i<m; ++i)
min_edge[i] = {{X[i], Y[i], min(X[i], Y[i])}};
sort(ALL(min_edge), [](array<int, 3> x, array<int, 3> y){return x[2] > y[2];});
DSU mst_min(n);
for(auto i: min_edge)
mst_min.join_set(i[0], i[1], i[2]);
vector<pair<int,int>> min_chain = mst_min.get_chain();
// build tree line for maximum node
vector<array<int, 3>> max_edge(m);
for(int i = 0; i<m; ++i)
max_edge[i] = {{X[i], Y[i], max(X[i], Y[i])}};
sort(ALL(max_edge), [](array<int, 3> x, array<int, 3> y){return x[2] < y[2];});
DSU mst_max(n);
for(auto i: max_edge)
mst_max.join_set(i[0], i[1], i[2]);
vector<pair<int,int>> max_chain = mst_max.get_chain();
for(int i = 0; i<n; ++i) {
chain1[i] = min_chain[i].first;
pos1[chain1[i]] = i;
chain2[i] = max_chain[i].first;
pos2[chain2[i]] = i;
w1[0][i] = min_chain[i].second;
w2[0][i] = max_chain[i].second;
}
for(int j = 1; MASK(j) <= n; ++j)
for(int i = 0; i + MASK(j) <= n; ++i){
w1[j][i] = min(w1[j-1][i], w1[j-1][i + MASK(j-1)]);
w2[j][i] = max(w2[j-1][i], w2[j-1][i + MASK(j-1)]);
}
for(int i = 0; i<n; ++i) query[pos1[i] + 1] = pos2[i] + 1;
for(int i = 0; i < q; ++i){
pair<int, int> spread1 = spread_min(pos1[S[i]], L[i]);
pair<int, int> spread2 = spread_max(pos2[E[i]], R[i]);
spread1.first++; spread1.second++; spread2.first++; spread2.second++;
destroyQuery[spread1.first-1].push_back({{spread2.first, spread2.second, i}});
createQuery[spread1.second].push_back({{spread2.first, spread2.second, i}});
}
FenwickTree bit(n);
for(int i = 1; i<=n; ++i){
bit.update(query[i], 1);
for(array<int, 3> j: destroyQuery[i]){
ans[j[2]] -= bit.get(j[0], j[1]);
}
for(array<int, 3> j: createQuery[i]){
ans[j[2]] += bit.get(j[0], j[1]);
}
}
for(int i = 0; i<q; ++i) ans[i] = (ans[i] > 0);
return ans;
}
// int main(void){
// ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
// int n, m, q; cin >> n >> m >> q;
// vector<int> X, Y;
// for(int i = 0; i<m; ++i){
// int u, v; cin >> u >> v;
// X.push_back(u); Y.push_back(v);
// }
// vector<int> S(q), E(q), L(q), R(q);
// for(int i = 0; i<q; ++i){
// cin >> S[i] >> E[i] >> L[i] >> R[i];
// }
// printArr(check_validity(n, X, Y, S, E, L, R));
// return 0;
// }
Compilation message (stderr)
werewolf.cpp: In function 'std::vector<int> check_validity(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
werewolf.cpp:222:28: warning: comparison of integer expressions of different signedness: 'long long unsigned int' and 'int' [-Wsign-compare]
222 | for(int j = 1; MASK(j) <= n; ++j)
| ^
werewolf.cpp:223:32: warning: comparison of integer expressions of different signedness: 'long long unsigned int' and 'int' [-Wsign-compare]
223 | for(int i = 0; i + MASK(j) <= n; ++i){
| ~~~~~~~~~~~~^~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |