QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#823651 | #1869. Power Station of Art | ninjadoggy1234 | AC ✓ | 261ms | 32208kb | C++20 | 16.3kb | 2024-12-21 08:48:20 | 2024-12-21 08:48:20 |
Judging History
answer
#include <bits/stdc++.h>
#ifdef LOCAL_RUN
#include <filesystem>
#endif
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#define int long long
#define FOR1(i, b) for(int i = 0; i < b; i++)
#define FOR2(i, a, b) for(int i = a; i < b; i++)
#define FOR(...) EXPAND(FOR_SELECT(__VA_ARGS__, FOR2, FOR1)(__VA_ARGS__))
#define FOR_SELECT(_1, _2, _3, NAME, ...) NAME
#define EXPAND(x) x
#define ALL(vec) vec.begin(),vec.end()
#define P(var) cerr << #var << ": " << var << "\n"
#define SZ(arr) (int)arr.size()
using namespace std;
template<typename T, size_t... Dims>struct Arr; template<size_t... Dims>struct total_size; template<size_t First, size_t... Rest>struct total_size<First, Rest...> { static constexpr size_t value = First * total_size<Rest...>::value; }; template<>struct total_size<> { static constexpr size_t value = 1; }; template<typename T, size_t... Dims>struct ArrProxy; template<typename T, size_t FirstDim, size_t... RestDims>struct ArrProxy<T, FirstDim, RestDims...> { T* data; constexpr ArrProxy(T* data_) noexcept :data(data_) {}constexpr ArrProxy<T, RestDims...>operator[](size_t index)noexcept { return ArrProxy<T, RestDims...>(data + index * total_size<RestDims...>::value); }constexpr ArrProxy<const T, RestDims...>operator[](size_t index)const noexcept { return ArrProxy<const T, RestDims...>(data + index * total_size<RestDims...>::value); }ArrProxy& operator=(const Arr<T, RestDims...>& other)noexcept { for (size_t i = 0; i < total_size<RestDims...>::value; ++i) { data[i] = other.data[i]; }return*this; } }; template<typename T, size_t Dim>struct ArrProxy<T, Dim> { T* data; constexpr ArrProxy(T* data_)noexcept :data(data_) {}constexpr T& operator[](size_t index)noexcept { return data[index]; }constexpr const T& operator[](size_t index)const noexcept { return data[index]; }ArrProxy& operator=(const Arr<T, Dim>& other)noexcept { for (size_t i = 0; i < Dim; ++i) { data[i] = other.data[i]; }return*this; } }; template<typename T, size_t FirstDim, size_t... RestDims>struct Arr<T, FirstDim, RestDims...> { static constexpr size_t totalSize = total_size<FirstDim, RestDims...>::value; array<T, totalSize>data; constexpr Arr()noexcept = default; constexpr Arr(const T& value)noexcept { data.fill(value); }template<typename... Args, typename = enable_if_t<sizeof...(Args) == totalSize>>constexpr Arr(Args... args)noexcept :data{ static_cast<T>(args)... } {}Arr(initializer_list<T>il) { size_t i = 0; for (auto it = il.begin(); it != il.end() && i < data.size(); ++it, ++i)data[i] = *it; }constexpr ArrProxy<T, RestDims...>operator[](size_t index)noexcept { return ArrProxy<T, RestDims...>(data.data() + index * total_size<RestDims...>::value); }constexpr ArrProxy<const T, RestDims...>operator[](size_t index)const noexcept { return ArrProxy<const T, RestDims...>(data.data() + index * total_size<RestDims...>::value); }Arr& operator+=(const Arr& o)noexcept { for (size_t i = 0; i < data.size(); ++i) { data[i] += o.data[i]; }return*this; }Arr& operator+=(const T& val)noexcept { for (size_t i = 0; i < data.size(); ++i) { data[i] += val; }return*this; }Arr& operator-=(const Arr& o)noexcept { for (size_t i = 0; i < data.size(); ++i) { data[i] -= o.data[i]; }return*this; }void Fill(const T& value)noexcept { for (size_t i = 0; i < data.size(); ++i) { data[i] = value; } }using iterator = typename array<T, totalSize>::iterator; using const_iterator = typename array<T, totalSize>::const_iterator; iterator begin()noexcept { return data.begin(); }const_iterator begin()const noexcept { return data.begin(); }iterator end()noexcept { return data.end(); }const_iterator end()const noexcept { return data.end(); }Arr& operator=(const ArrProxy<T, RestDims...>& proxy)noexcept { constexpr size_t subSize = total_size<RestDims...>::value; for (size_t i = 0; i < FirstDim; ++i) { Arr<T, RestDims...>subArr; subArr = proxy[i]; copy(subArr.data.begin(), subArr.data.end(), data.begin() + i * subSize); }return*this; }template<typename U, size_t... Ds>friend ostream& operator<<(ostream& os, const Arr<U, Ds...>& arr)noexcept; template<typename U, size_t... Ds>friend istream& operator>>(istream& is, Arr<U, Ds...>& arr)noexcept; }; template<typename T, size_t Dim>struct Arr<T, Dim> { static constexpr size_t totalSize = Dim; array<T, totalSize>data; constexpr Arr(const array<T, totalSize>& arr) : data(arr) {} constexpr Arr()noexcept = default; constexpr Arr(const T& value)noexcept { data.fill(value); }template<typename... Args, typename = enable_if_t<sizeof...(Args) == totalSize>>constexpr Arr(Args... args)noexcept :data{ static_cast<T>(args)... } {}Arr(initializer_list<T>il) { size_t i = 0; for (auto it = il.begin(); it != il.end() && i < data.size(); ++it, ++i)data[i] = *it; }constexpr T& operator[](size_t index)noexcept { return data[index]; }constexpr const T& operator[](size_t index)const noexcept { return data[index]; }Arr& operator+=(const Arr& o)noexcept { for (size_t i = 0; i < data.size(); ++i) { data[i] += o.data[i]; }return*this; }Arr& operator+=(const T& val)noexcept { for (size_t i = 0; i < data.size(); ++i) { data[i] += val; }return*this; }Arr& operator-=(const Arr& o)noexcept { for (size_t i = 0; i < data.size(); ++i) { data[i] -= o.data[i]; }return*this; }void Fill(const T& value)noexcept { for (size_t i = 0; i < data.size(); ++i) { data[i] = value; } }using iterator = typename array<T, totalSize>::iterator; using const_iterator = typename array<T, totalSize>::const_iterator; iterator begin()noexcept { return data.begin(); }const_iterator begin()const noexcept { return data.begin(); }iterator end()noexcept { return data.end(); }const_iterator end()const noexcept { return data.end(); }Arr& operator=(const ArrProxy<T, Dim>& proxy)noexcept { for (size_t i = 0; i < totalSize; ++i) { data[i] = proxy[i]; }return*this; }template<typename U, size_t D>friend ostream& operator<<(ostream& os, const Arr<U, D>& arr)noexcept; template<typename U, size_t D>friend istream& operator>>(istream& is, Arr<U, D>& arr)noexcept; }; template<typename T, size_t FirstDim, size_t... RestDims>ostream& operator<<(ostream& os, const Arr<T, FirstDim, RestDims...>& arr)noexcept { for (size_t i = 0; i < FirstDim; ++i) { os << arr[i]; os << "\n"; }return os; }template<typename T, size_t Dim>ostream& operator<<(ostream& os, const Arr<T, Dim>& arr)noexcept { for (size_t i = 0; i < Dim; ++i) { os << arr[i]; if (i != Dim - 1)os << " "; }os << "\n"; return os; }template<typename T, size_t FirstDim, size_t... RestDims>ostream& operator<<(ostream& os, const ArrProxy<T, FirstDim, RestDims...>& proxy)noexcept { for (size_t i = 0; i < FirstDim; ++i) { os << proxy[i]; if (i != FirstDim - 1)os << "\n"; }return os; }template<typename T, size_t Dim>ostream& operator<<(ostream& os, const ArrProxy<T, Dim>& proxy)noexcept { for (size_t i = 0; i < Dim; ++i) { os << proxy[i]; if (i != Dim - 1)os << " "; }return os; }template<typename T, size_t... Dims>istream& operator>>(istream& is, Arr<T, Dims...>& arr)noexcept { for (size_t i = 0; i < Arr<T, Dims...>::totalSize; ++i) { is >> arr.data[i]; }return is; }template<typename T, size_t Dim>istream& operator>>(istream& is, Arr<T, Dim>& arr)noexcept { for (size_t i = 0; i < Dim; ++i) { is >> arr.data[i]; }return is; }template<typename T, size_t... Dims>bool operator<(const Arr<T, Dims...>& a, const Arr<T, Dims...>& b)noexcept { return a.data < b.data; }template<typename T, size_t... Dims>bool operator==(const Arr<T, Dims...>& a, const Arr<T, Dims...>& b)noexcept { return a.data == b.data; }template<typename T, size_t... Dims>bool operator!=(const Arr<T, Dims...>& a, const Arr<T, Dims...>& b)noexcept { return a.data != b.data; }template<typename T, size_t... Dims>bool operator<=(const Arr<T, Dims...>& a, const Arr<T, Dims...>& b)noexcept { return a.data <= b.data; }template<typename T, size_t... Dims>bool operator>(const Arr<T, Dims...>& a, const Arr<T, Dims...>& b)noexcept { return a.data > b.data; }template<typename T, size_t... Dims>bool operator>=(const Arr<T, Dims...>& a, const Arr<T, Dims...>& b)noexcept { return a.data >= b.data; }template<typename T, size_t Dim>bool operator<(const Arr<T, Dim>& a, const Arr<T, Dim>& b)noexcept { return a.data < b.data; }template<typename T, size_t Dim>bool operator==(const Arr<T, Dim>& a, const Arr<T, Dim>& b)noexcept { return a.data == b.data; }template<typename T, size_t Dim>bool operator!=(const Arr<T, Dim>& a, const Arr<T, Dim>& b)noexcept { return a.data != b.data; }template<typename T, size_t Dim>bool operator<=(const Arr<T, Dim>& a, const Arr<T, Dim>& b)noexcept { return a.data <= b.data; }template<typename T, size_t Dim>bool operator>(const Arr<T, Dim>& a, const Arr<T, Dim>& b)noexcept { return a.data > b.data; }template<typename T, size_t Dim>bool operator>=(const Arr<T, Dim>& a, const Arr<T, Dim>& b)noexcept { return a.data >= b.data; }namespace std { template<typename T, size_t FirstDim, size_t... RestDims>struct tuple_size<Arr<T, FirstDim, RestDims...>> : integral_constant<size_t, FirstDim> {}; template<size_t N, typename T, size_t FirstDim, size_t... RestDims>struct tuple_element<N, Arr<T, FirstDim, RestDims...>> { using type = ArrProxy<T, RestDims...>; }; template<typename T, size_t Dim>struct tuple_size<Arr<T, Dim>> : integral_constant<size_t, Dim> {}; template<size_t N, typename T, size_t Dim>struct tuple_element<N, Arr<T, Dim>> { using type = T; }; template<typename T, size_t FirstDim, size_t... RestDims>struct tuple_size<ArrProxy<T, FirstDim, RestDims...>> : integral_constant<size_t, FirstDim> {}; template<typename T, size_t Dim>struct tuple_size<ArrProxy<T, Dim>> : integral_constant<size_t, Dim> {}; template<size_t N, typename T, size_t FirstDim, size_t... RestDims>struct tuple_element<N, ArrProxy<T, FirstDim, RestDims...>> { using type = ArrProxy<T, RestDims...>; }; template<size_t N, typename T, size_t Dim>struct tuple_element<N, ArrProxy<T, Dim>> { using type = T; }; }template<size_t N, typename T, size_t FirstDim, size_t... RestDims>decltype(auto) get(ArrProxy<T, FirstDim, RestDims...>& proxy) { return proxy[N]; }template<size_t N, typename T, size_t FirstDim, size_t... RestDims>decltype(auto) get(const ArrProxy<T, FirstDim, RestDims...>& proxy) { return proxy[N]; }template<size_t N, typename T, size_t FirstDim, size_t... RestDims>decltype(auto) get(ArrProxy<T, FirstDim, RestDims...>&& proxy) { return move(proxy[N]); }template<size_t N, typename T, size_t Dim>decltype(auto) get(Arr<T, Dim>& arr) { return arr[N]; }template<size_t N, typename T, size_t Dim>decltype(auto) get(const Arr<T, Dim>& arr) { return arr[N]; }template<size_t N, typename T, size_t Dim>decltype(auto) get(Arr<T, Dim>&& arr) { return move(arr[N]); }
template<int D, typename T> struct MVec : vector<MVec<D - 1, T>> { MVec() :MVec(0) {} template<typename U, typename... Args> MVec(U n = U(), Args...args) : vector<MVec<D - 1, T>>(n, MVec<D - 1, T>(args...)) {} friend ostream& operator<<(ostream& s, const MVec& v) { for (size_t i = 0; i < v.size(); ++i)s << v[i]; return s; } void Fill(const T& x) { for (auto& v : *this)v.Fill(x); } MVec& operator+=(const MVec& o) { FOR(i, this->size())(*this)[i] += o[i]; return *this; } MVec& operator-=(const MVec& o) { FOR(i, this->size())(*this)[i] -= o[i]; return *this; } MVec operator+(const MVec& o)const { MVec r(this->size()); FOR(i, this->size())r[i] = (*this)[i] + o[i]; return r; } MVec operator-(const MVec& o)const { MVec r(this->size()); FOR(i, this->size())r[i] = (*this)[i] - o[i]; return r; } friend istream& operator>>(istream& is, MVec& v) { for (auto& e : v)is >> e; return is; } }; template<typename T> using Vec = MVec<1, T>; template<typename T>ostream& operator<<(ostream& os, const MVec<1, T>& vec) noexcept { FOR(i, SZ(vec))os << vec[i] << " \n"[i == SZ(vec) - 1]; return os; }template<typename T, size_t... Dims>ostream& operator<<(ostream& os, const MVec<1, Arr<T, Dims...>>& vec) noexcept { for (const auto& arr : vec)os << arr; return os; }
template<typename T> struct MVec<1, T> : vector<T> { MVec() : MVec(0) {} using vector<T>::vector; MVec(initializer_list<T> l) : vector<T>(l) {} void Fill(const T& x) { fill(this->begin(), this->end(), x); } MVec operator+(const MVec& o)const { MVec r(this->size()); FOR(i, this->size())r[i] = (*this)[i] + o[i]; return r; } MVec operator-(const MVec& o)const { MVec r(this->size()); FOR(i, this->size())r[i] = (*this)[i] - o[i]; return r; } MVec& operator+=(const MVec& o) { FOR(i, this->size())(*this)[i] += o[i]; return *this; } MVec& operator-=(const MVec& o) { FOR(i, this->size())(*this)[i] -= o[i]; return *this; } friend istream& operator>>(istream& s, MVec& v) { for (auto& e : v)s >> e; return s; } };
template<typename Edge> struct Graph { struct OutgoingEdges { const Graph* g; int l, r; OutgoingEdges(const Graph* g, int l, int r) : g(g), l(l), r(r) {} const Edge* begin() const { return l == r ? nullptr : &g->prepared_edges[l]; } const Edge* end() const { return l == r ? nullptr : &g->prepared_edges[r]; } }; vector<Edge> prepared_edges; vector<pair<int, Edge>> edges; vector<int> start; int N; inline int size() { return N - 1; } Graph() {} Graph(int N) :N(N + 1), start(N + 2) {} void AddEdge(int from, const Edge& e) { edges.emplace_back(from, e); } void Prepare() { for (const auto& e : edges) ++start[e.first + 1]; for (int i = 1; i < N; ++i) start[i] += start[i - 1]; prepared_edges.resize(edges.size() + 1); auto counter = start; for (const auto& e : edges) prepared_edges[counter[e.first]++] = e.second; } OutgoingEdges operator[](int from) const { return (from < 0 || from + 1 >= start.size()) ? OutgoingEdges(this, 0, 0) : OutgoingEdges(this, start[from], start[from + 1]); } };
inline Graph<int> ReadGraph(int N, int M, bool undirected = true, bool one_indexed = true) { Graph<int> adj(N); FOR(i, M) { int a, b; cin >> a >> b; if (one_indexed) { a--; b--; }adj.AddEdge(a, b); if (undirected) { adj.AddEdge(b, a); } }adj.Prepare(); return adj; }
inline Graph<Arr<int, 2>> ReadWeightedGraph(int N, int M, bool undirected = true, bool one_indexed = true) { Graph<Arr<int, 2>> adj(N); FOR(i, M) { int a, b, d; cin >> a >> b >> d; if (one_indexed) { a--; b--; }adj.AddEdge(a, { b,d }); if (undirected) { adj.AddEdge(b, { a,d }); } }adj.Prepare(); return adj; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
template<class T> bool ckmin(T& a, const T& b) { return a > b ? a = b, 1 : 0; }
const string YN[2] = { "NO\n","YES\n" };
const int oo = 3e18;
struct Solution {
const static bool kReadTestCases = 1;
stringstream out;
void Solve(stringstream& out, const bool kNeedToClear = false, int test_case = 1) {
int N, M; cin >> N >> M;
auto adj = ReadGraph(N, M);
Vec<int> a(N), b(N);
string c1, c2;
cin >> a >> c1 >> b >> c2;
Vec<int> color(N);
bool bipartite = true;
Vec<int> nodes; nodes.reserve(N);
Vec<Arr<int, 2>> c1s, c2s; c1s.reserve(N); c2s.reserve(N);
function<void(int, int)> DFS = [&](int node, int c) {
if (color[node] != 0) {
if (color[node] != c) {
bipartite = false;
}
return;
}
color[node] = c;
nodes.push_back(node);
for (int next : adj[node]) {
DFS(next, 3 - c);
}
};
bool good = true;
FOR(i, N) {
if (color[i] == 0) {
nodes.clear();
c1s.clear();
c2s.clear();
bipartite = true;
DFS(i, 1);
int p1 = 0, p2 = 0;
for (int n : nodes) {
p1 += c1[n] == 'R';
p2 += c2[n] == 'R';
if (bipartite) {
if (color[n] == 1) {
c1s.emplace_back(a[n], c1[n] == 'R');
c2s.emplace_back(b[n], c2[n] == 'R');
} else {
c1s.emplace_back(a[n], 1 - (c1[n] == 'R'));
c2s.emplace_back(b[n], 1 - (c2[n] == 'R'));
}
} else {
c1s.emplace_back(a[n], 0);
c2s.emplace_back(b[n], 0);
}
}
sort(ALL(c1s));
sort(ALL(c2s));
if (p1 % 2 != p2 % 2 || c1s != c2s) {
good = false;
break;
}
}
}
out << YN[good];
}
void Precompute() {
}
stringstream& Run() {
Precompute();
out << fixed << setprecision(20);
int num_cases = 1;
if (kReadTestCases)cin >> num_cases;
for (int test_case = 1; test_case <= num_cases; test_case++) {
Solve(out, test_case < num_cases, test_case);
}
return out;
}
};
#ifdef LOCAL_RUN
const int kTestCase = 0;
#include "_LocalIO.h"
//#include "_StressTester.h"
#endif
Solution solution;
int32_t main() {
#ifdef LOCAL_RUN
//StressTester::Run(__FILE__);
if (LocalIO::PerformRuns(__FILE__)) return 0;
#endif
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
auto& out = solution.Run();
cout << out.str(); cout.flush();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3596kb
input:
3 2 1 1 2 3 4 RR 4 3 BB 3 2 1 2 2 3 1 1 1 RBR 1 1 1 BBB 3 3 1 2 2 3 3 1 1 1 1 RBR 1 1 1 BBB
output:
YES NO YES
result:
ok 3 lines
Test #2:
score: 0
Accepted
time: 261ms
memory: 32208kb
input:
25054 5 10 4 5 4 2 4 3 4 1 5 2 5 3 5 1 2 3 2 1 3 1 12 2 9 10 7 RRRBB 10 2 9 7 12 RRBRB 1 0 4 R 4 R 8 4 4 3 1 5 8 5 6 5 7 2 11 10 9 6 3 5 RBRBBRBR 7 2 10 11 6 5 3 9 RBRBBRBR 7 4 7 2 5 1 5 6 5 4 12 5 9 14 5 12 12 RRBRBRR 14 12 9 5 12 12 5 RBBRBRB 10 1 4 6 5 3 2 9 7 3 11 11 6 8 RRRBRRBBBR 5 3 2 3 7 9 1...
output:
YES YES YES YES YES YES YES YES YES NO YES NO YES NO NO YES YES YES NO YES NO YES YES NO YES YES NO YES NO YES YES YES YES NO YES YES NO YES YES YES YES YES YES YES YES YES YES YES YES YES YES NO NO YES NO YES YES YES YES NO YES YES YES YES YES YES YES YES YES YES YES YES NO YES YES YES NO YES NO NO...
result:
ok 25054 lines