結果
| 問題 |
No.5005 3-SAT
|
| ユーザー |
|
| 提出日時 | 2022-04-29 15:21:09 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,904 ms / 2,000 ms |
| コード長 | 17,615 bytes |
| コンパイル時間 | 3,375 ms |
| 実行使用メモリ | 7,776 KB |
| スコア | 102,968 |
| 最終ジャッジ日時 | 2022-04-29 15:24:29 |
| 合計ジャッジ時間 | 200,261 ms |
|
ジャッジサーバーID (参考情報) |
judge11 / judge15 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 100 |
ソースコード
/**
* date : 2022-04-29 15:21:04
*/
#define NDEBUG
using namespace std;
// intrinstic
#include <immintrin.h>
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfenv>
#include <cfloat>
#include <chrono>
#include <cinttypes>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <ios>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <streambuf>
#include <string>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
// utility
namespace Nyaan {
using ll = long long;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
template <typename T>
using V = vector<T>;
template <typename T>
using VV = vector<vector<T>>;
using vi = vector<int>;
using vl = vector<long long>;
using vd = V<double>;
using vs = V<string>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<long long>>;
template <typename T, typename U>
struct P : pair<T, U> {
template <typename... Args>
P(Args... args) : pair<T, U>(args...) {}
using pair<T, U>::first;
using pair<T, U>::second;
P &operator+=(const P &r) {
first += r.first;
second += r.second;
return *this;
}
P &operator-=(const P &r) {
first -= r.first;
second -= r.second;
return *this;
}
P &operator*=(const P &r) {
first *= r.first;
second *= r.second;
return *this;
}
template <typename S>
P &operator*=(const S &r) {
first *= r, second *= r;
return *this;
}
P operator+(const P &r) const { return P(*this) += r; }
P operator-(const P &r) const { return P(*this) -= r; }
P operator*(const P &r) const { return P(*this) *= r; }
template <typename S>
P operator*(const S &r) const {
return P(*this) *= r;
}
P operator-() const { return P{-first, -second}; }
};
using pl = P<ll, ll>;
using pi = P<int, int>;
using vp = V<pl>;
constexpr int inf = 1001001001;
constexpr long long infLL = 4004004004004004004LL;
template <typename T>
int sz(const T &t) {
return t.size();
}
template <typename T, typename U>
inline bool amin(T &x, U y) {
return (y < x) ? (x = y, true) : false;
}
template <typename T, typename U>
inline bool amax(T &x, U y) {
return (x < y) ? (x = y, true) : false;
}
template <typename T>
inline T Max(const vector<T> &v) {
return *max_element(begin(v), end(v));
}
template <typename T>
inline T Min(const vector<T> &v) {
return *min_element(begin(v), end(v));
}
template <typename T>
inline long long Sum(const vector<T> &v) {
return accumulate(begin(v), end(v), 0LL);
}
template <typename T>
int lb(const vector<T> &v, const T &a) {
return lower_bound(begin(v), end(v), a) - begin(v);
}
template <typename T>
int ub(const vector<T> &v, const T &a) {
return upper_bound(begin(v), end(v), a) - begin(v);
}
constexpr long long TEN(int n) {
long long ret = 1, x = 10;
for (; n; x *= x, n >>= 1) ret *= (n & 1 ? x : 1);
return ret;
}
template <typename T, typename U>
pair<T, U> mkp(const T &t, const U &u) {
return make_pair(t, u);
}
template <typename T>
vector<T> mkrui(const vector<T> &v, bool rev = false) {
vector<T> ret(v.size() + 1);
if (rev) {
for (int i = int(v.size()) - 1; i >= 0; i--) ret[i] = v[i] + ret[i + 1];
} else {
for (int i = 0; i < int(v.size()); i++) ret[i + 1] = ret[i] + v[i];
}
return ret;
};
template <typename T>
vector<T> mkuni(const vector<T> &v) {
vector<T> ret(v);
sort(ret.begin(), ret.end());
ret.erase(unique(ret.begin(), ret.end()), ret.end());
return ret;
}
template <typename F>
vector<int> mkord(int N,F f) {
vector<int> ord(N);
iota(begin(ord), end(ord), 0);
sort(begin(ord), end(ord), f);
return ord;
}
template <typename T>
vector<int> mkinv(vector<T> &v) {
int max_val = *max_element(begin(v), end(v));
vector<int> inv(max_val + 1, -1);
for (int i = 0; i < (int)v.size(); i++) inv[v[i]] = i;
return inv;
}
vector<int> mkiota(int n) {
vector<int> ret(n);
iota(begin(ret), end(ret), 0);
return ret;
}
template <typename T>
T mkrev(const T &v) {
T w{v};
reverse(begin(w), end(w));
return w;
}
template <typename T>
bool nxp(vector<T> &v) {
return next_permutation(begin(v), end(v));
}
#define inV(T, v, n) \
vector<T> v(n); \
in(v)
#define inVV(T, v, h, w) \
vector<vector<T>> v(h, vector<T>(w)); \
in(v);
template <typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;
// 区間:半開区間 (ng, ok] または [ok, ng)
template <typename T, typename F>
T binary_search(T ng, T ok, const F& f) {
if constexpr (is_integral<T>::value == true) {
while (abs(ok - ng) > 1) {
T x = (ok + ng) / 2;
(f(x) ? ok : ng) = x;
}
return ok;
} else {
for (int iter = 0; iter < 60; iter++) {
T x = (ok + ng) / 2;
(f(x) ? ok : ng) = x;
}
return ok;
}
}
// 解区間 (l, r)
template <typename T, typename F>
void ternary_search(T l, T r, const F& f, bool greater = false) {
if constexpr (is_integral<T>::value == true) {
while (abs(l - r) > 2) {
T llr = (l * 2 + r * 1) / 3;
T lrr = (l * 1 + r * 2) / 3;
bool flag = f(llr) < f(lrr);
if (flag != greater) {
r = lrr;
} else {
l = llr;
}
}
return (l + r) / 2;
} else {
for (int iter = 0; iter < 80; iter++) {
T llr = (l * 2 + r * 1) / 3;
T lrr = (l * 1 + r * 2) / 3;
bool flag = f(llr) < f(lrr);
if (flag != greater) {
r = lrr;
} else {
l = llr;
}
}
return (l + r) / 2;
}
}
} // namespace Nyaan
// bit operation
namespace Nyaan {
__attribute__((target("popcnt"))) inline int popcnt(const u64 &a) {
return _mm_popcnt_u64(a);
}
inline int lsb(const u64 &a) { return a ? __builtin_ctzll(a) : 64; }
inline int ctz(const u64 &a) { return a ? __builtin_ctzll(a) : 64; }
inline int msb(const u64 &a) { return a ? 63 - __builtin_clzll(a) : -1; }
template <typename T>
inline int gbit(const T &a, int i) {
return (a >> i) & 1;
}
template <typename T>
inline void sbit(T &a, int i, bool b) {
if (gbit(a, i) != b) a ^= T(1) << i;
}
constexpr long long PW(int n) { return 1LL << n; }
constexpr long long MSK(int n) { return (1LL << n) - 1; }
} // namespace Nyaan
// inout
namespace Nyaan {
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
os << p.first << " " << p.second;
return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
is >> p.first >> p.second;
return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
int s = (int)v.size();
for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
for (auto &x : v) is >> x;
return is;
}
istream &operator>>(istream &is, __int128_t &x) {
string S;
is >> S;
x = 0;
int flag = 0;
for (auto &c : S) {
if (c == '-') {
flag = true;
continue;
}
x *= 10;
x += c - '0';
}
if (flag) x = -x;
return is;
}
istream &operator>>(istream &is, __uint128_t &x) {
string S;
is >> S;
x = 0;
for (auto &c : S) {
x *= 10;
x += c - '0';
}
return is;
}
ostream &operator<<(ostream &os, __int128_t x) {
if (x == 0) return os << 0;
if (x < 0) os << '-', x = -x;
string S;
while (x) S.push_back('0' + x % 10), x /= 10;
reverse(begin(S), end(S));
return os << S;
}
ostream &operator<<(ostream &os, __uint128_t x) {
if (x == 0) return os << 0;
string S;
while (x) S.push_back('0' + x % 10), x /= 10;
reverse(begin(S), end(S));
return os << S;
}
void in() {}
template <typename T, class... U>
void in(T &t, U &...u) {
cin >> t;
in(u...);
}
void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u) {
cout << t;
if (sizeof...(u)) cout << sep;
out(u...);
}
void outr() {}
template <typename T, class... U, char sep = ' '>
void outr(const T &t, const U &...u) {
cout << t;
outr(u...);
}
struct IoSetupNya {
IoSetupNya() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
cout << fixed << setprecision(15);
cerr << fixed << setprecision(7);
}
} iosetupnya;
} // namespace Nyaan
// debug
namespace DebugImpl {
template <typename U, typename = void>
struct is_specialize : false_type {};
template <typename U>
struct is_specialize<
U, typename conditional<false, typename U::iterator, void>::type>
: true_type {};
template <typename U>
struct is_specialize<
U, typename conditional<false, decltype(U::first), void>::type>
: true_type {};
template <typename U>
struct is_specialize<U, enable_if_t<is_integral<U>::value, void>> : true_type {
};
void dump(const char& t) { cerr << t; }
void dump(const string& t) { cerr << t; }
void dump(const bool& t) { cerr << (t ? "true" : "false"); }
void dump(__int128_t t) {
if (t == 0) cerr << 0;
if (t < 0) cerr << '-', t = -t;
string S;
while (t) S.push_back('0' + t % 10), t /= 10;
reverse(begin(S), end(S));
cerr << S;
}
void dump(__uint128_t t) {
if (t == 0) cerr << 0;
string S;
while (t) S.push_back('0' + t % 10), t /= 10;
reverse(begin(S), end(S));
cerr << S;
}
template <typename U,
enable_if_t<!is_specialize<U>::value, nullptr_t> = nullptr>
void dump(const U& t) {
cerr << t;
}
template <typename T>
void dump(const T& t, enable_if_t<is_integral<T>::value>* = nullptr) {
string res;
if (t == Nyaan::inf) res = "inf";
if constexpr (is_signed<T>::value) {
if (t == -Nyaan::inf) res = "-inf";
}
if constexpr (sizeof(T) == 8) {
if (t == Nyaan::infLL) res = "inf";
if constexpr (is_signed<T>::value) {
if (t == -Nyaan::infLL) res = "-inf";
}
}
if (res.empty()) res = to_string(t);
cerr << res;
}
template <typename T, typename U>
void dump(const pair<T, U>&);
template <typename T>
void dump(const pair<T*, int>&);
template <typename T>
void dump(const T& t,
enable_if_t<!is_void<typename T::iterator>::value>* = nullptr) {
cerr << "[ ";
for (auto it = t.begin(); it != t.end();) {
dump(*it);
cerr << (++it == t.end() ? "" : ", ");
}
cerr << " ]";
}
template <typename T, typename U>
void dump(const pair<T, U>& t) {
cerr << "( ";
dump(t.first);
cerr << ", ";
dump(t.second);
cerr << " )";
}
template <typename T>
void dump(const pair<T*, int>& t) {
cerr << "[ ";
for (int i = 0; i < t.second; i++) {
dump(t.first[i]);
cerr << (i == t.second - 1 ? "" : ", ");
}
cerr << " ]";
}
void trace() { cerr << endl; }
template <typename Head, typename... Tail>
void trace(Head&& head, Tail&&... tail) {
cerr << " ";
dump(head);
if (sizeof...(tail) != 0) cerr << ",";
trace(forward<Tail>(tail)...);
}
} // namespace DebugImpl
#ifdef NyaanDebug
#define trc(...) \
do { \
cerr << "## " << #__VA_ARGS__ << " = "; \
DebugImpl::trace(__VA_ARGS__); \
} while (0)
#else
#define trc(...) (void(0))
#endif
// macro
#define each(x, v) for (auto&& x : v)
#define each2(x, y, v) for (auto&& [x, y] : v)
#define all(v) (v).begin(), (v).end()
#define rep(i, N) for (long long i = 0; i < (long long)(N); i++)
#define repr(i, N) for (long long i = (long long)(N)-1; i >= 0; i--)
#define rep1(i, N) for (long long i = 1; i <= (long long)(N); i++)
#define repr1(i, N) for (long long i = (N); (long long)(i) > 0; i--)
#define reg(i, a, b) for (long long i = (a); i < (b); i++)
#define regr(i, a, b) for (long long i = (b)-1; i >= (a); i--)
#define fi first
#define se second
#define ini(...) \
int __VA_ARGS__; \
in(__VA_ARGS__)
#define inl(...) \
long long __VA_ARGS__; \
in(__VA_ARGS__)
#define ins(...) \
string __VA_ARGS__; \
in(__VA_ARGS__)
#define in2(s, t) \
for (int i = 0; i < (int)s.size(); i++) { \
in(s[i], t[i]); \
}
#define in3(s, t, u) \
for (int i = 0; i < (int)s.size(); i++) { \
in(s[i], t[i], u[i]); \
}
#define in4(s, t, u, v) \
for (int i = 0; i < (int)s.size(); i++) { \
in(s[i], t[i], u[i], v[i]); \
}
#define die(...) \
do { \
Nyaan::out(__VA_ARGS__); \
return; \
} while (0)
namespace Nyaan {
void solve();
}
int main() { Nyaan::solve(); }
//
struct Timer {
chrono::high_resolution_clock::time_point st;
Timer() { reset(); }
void reset() { st = chrono::high_resolution_clock::now(); }
chrono::milliseconds::rep elapsed() {
auto ed = chrono::high_resolution_clock::now();
return chrono::duration_cast<chrono::milliseconds>(ed - st).count();
}
};
Timer timer;
constexpr int limit = 1900;
// https://github.com/not522/CompetitiveProgramming/blob/master/include/math/sat.hpp
namespace not_522 {
class SatSolver {
private:
vector<vector<pair<int, bool>>> cl;
map<pair<int, bool>, vector<int>> w;
vector<int> reason, level, que, activity;
int n, qi;
void enqueue(int v, bool a, int r = -1) {
assigns[v] = a;
reason[v] = r;
level[v] = (que.empty() ? 1 : level[que.back()]);
que.emplace_back(v);
}
void add(const vector<pair<int, bool>> &clause) {
for (auto l : clause) {
w[l].emplace_back(cl.size());
}
cl.emplace_back(clause);
}
void analyze(int confl) {
int i = que.size(), lv = 1;
unordered_set<int> used;
vector<pair<int, bool>> learnt;
for (int cnt = 0; cnt || used.empty(); --cnt) {
for (auto q : cl[confl]) {
if (!used.emplace(q.first).second) {
continue;
}
activity[q.first] += 1e5;
if (level[q.first] == level[que.back()]) {
++cnt;
} else {
learnt.emplace_back(q);
lv = max(lv, level[q.first]);
}
}
while (!used.count(que[--i])) {
;
}
confl = reason[que[i]];
}
learnt.emplace_back(que[i], !assigns[que[i]]);
for (; !que.empty() && level[que.back()] > lv; que.pop_back()) {
level[que.back()] = 0;
}
qi = que.size();
enqueue(learnt.back().first, learnt.back().second, cl.size());
add(learnt);
}
int propagate() {
for (; qi < int(que.size()); ++qi) {
for (int cr : w[make_pair(que[qi], !assigns[que[qi]])]) {
int cnt = 0;
for (auto &lit : cl[cr]) {
if (level[lit.first] == 0) {
activity[lit.first] += 1e3;
swap(lit, cl[cr][0]);
++cnt;
} else if (assigns[lit.first] == lit.second) {
swap(lit, cl[cr][0]);
cnt = -1;
break;
}
}
if (cnt == 0) {
return cr;
}
if (cnt == 1) {
enqueue(cl[cr][0].first, cl[cr][0].second, cr);
}
}
}
return -1;
}
public:
vector<bool> assigns;
SatSolver(int _n, const vector<vector<pair<int, bool>>> &clauses)
: reason(_n), level(_n), activity(_n), n(_n), qi(0), assigns(_n) {
for (const auto &clause : clauses) {
add(clause);
}
}
bool solve() {
while (true) {
if (timer.elapsed() > limit) return false;
int confl = propagate();
if (confl != -1) {
if (level[que.back()] == 1u) {
return false;
}
for (auto &a : activity) {
a /= 1.05;
}
analyze(confl);
} else {
int k = -1;
for (int i = 0; i < n; ++i) {
if (level[i] == 0 && (k == -1 || activity[k] < activity[i])) {
k = i;
}
}
if (k == -1) {
return true;
}
enqueue(k, assigns[k]);
++level[k];
}
}
}
};
} // namespace not_522
using namespace Nyaan;
void q() {
timer.reset();
int N = 2048;
int M = 256;
// int N = 5, M = 6;
vi a(N), b(N), c(N), p(N), q(N), r(N);
rep(i, N) in(a[i], b[i], c[i], p[i], q[i], r[i]);
string ans(M, '0');
int best = 0;
int ok = 0, ng = 1;
using Clause = vector<pair<int, bool>>;
while (timer.elapsed() < limit) {
int med;
if (ok == 0 and ng != N) {
med = ng;
} else {
if (ok + 1 == ng) break;
med = (ok + ng) / 2;
}
V<Clause> clauses;
rep(i, med) {
Clause cl;
cl.push_back(mkp(a[i], p[i]));
cl.push_back(mkp(b[i], q[i]));
cl.push_back(mkp(c[i], r[i]));
clauses.push_back(cl);
}
not_522::SatSolver sat(M, clauses);
bool f = sat.solve();
// trc(med, f);
// trc(sat.assigns);
if (ok == 0 and ng != N) {
if (f) {
if (ng >= 512)
ng += 50;
else
ng *= 2;
} else {
ok = ng / 2;
}
} else {
(f ? ok : ng) = med;
}
if (f and amax(best, med)) {
rep(i, M) ans[i] = (sat.assigns[i] ? '1' : '0');
}
cerr << med << " " << f << " " << timer.elapsed() << endl;
}
reverse(all(ans));
out(ans);
}
void Nyaan::solve() {
int T = 1;
// in(T);
while (T--) q();
}