QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#474802 | #6521. Swapping Operation | dnialh | TL | 0ms | 3528kb | C++20 | 6.3kb | 2024-07-13 05:30:39 | 2024-07-13 05:30:39 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
#define F0R(i,n) for (int i = 0; i < n; i++)
#define FOR(i,a,b) for (int i = a; i <= b; i++)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define FORd(i,a,b) for (int i = (b); i >= (a); i--)
#define trav(a, x) for (auto& a : x)
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define ins insert
#define lb lower_bound
#define ub upper_bound
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
const char nl = '\n';
const int MAX_N = 100011;
const ll INF = (1<<29) + 123;
const ll MOD = 1000000007; // 998244353
const ld PI = 4*atan((ld)1);
template <typename T> bool ckmin(T& a, const T& b) { return a > b ? a=b, 1 : 0; }
template <typename T> bool ckmax(T& a, const T& b) { return b > a ? a=b, 1 : 0; }
/**** Credit to chatgpt 4.0 ****/
// Stream operator for std::pair
template<typename T1, typename T2>
ostream& operator<<(ostream &out, const pair<T1, T2> &v) {
out << "(" << v.first << ", " << v.second << ")";
return out;
}
// Trait to check if a type is iterable
template<typename T, typename = void>
struct is_iterable : false_type {};
template<typename T>
struct is_iterable<T, void_t<decltype(begin(declval<T>())), decltype(end(declval<T>()))>> : true_type {};
// Stream operator for iterable types excluding std::string
template<typename TT>
typename enable_if<is_iterable<TT>::value && !is_same<TT, string>::value, ostream&>::type
operator<<(ostream& out, const TT& c) {
out << "{ ";
for (const auto& x : c) out << x << " ";
out << "}";
return out;
}
template<typename T>
ostream& operator<<(ostream& out, std::stack<T> container) {
std::vector<T> elements;
while (!container.empty()) {
elements.push_back(container.top());
container.pop();
}
std::reverse(elements.begin(), elements.end()); // Reverse to maintain order
return out << elements;
}
template<typename T>
ostream& operator<<(ostream& out, std::queue<T> container) {
std::vector<T> elements;
while (!container.empty()) {
elements.push_back(container.front());
container.pop();
}
return out << elements;
}
// Helper function to print std::priority_queue
template<typename T, typename Container, typename Compare>
ostream& operator<<(ostream& out, std::priority_queue<T, Container, Compare> pq) {
out << "{";
while (!pq.empty()) {
out << " " << pq.top();
pq.pop();
}
out << " }";
return out;
}
#ifdef DBG
void dbg_out() { cerr << endl; }
template<typename Head, typename... Tail>
void dbg_out(Head H, Tail... T) {
cerr << ' ' << H;
dbg_out(T...);
}
#define dbg(...) cerr << #__VA_ARGS__ << ":", dbg_out(__VA_ARGS__);
#define dbg_array(a, n) cerr << #a << ": { "; for(int i = 0; i < n; i++) cerr << a[i] << " "; cerr << "}\n";
#else
#define dbg(...)
#define dbg_array(a, n)
#endif
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
const int MX = 5;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t; cin >> t;
while (t--) {
int n; cin >> n;
int a[n]; F0R(i, n) cin >> a[i];
// now figure out the first and second missing thing from each side for each bit
pi left[MX], right[MX];
F0R(i, MX) {
left[i] = right[i] = {-1, -1};
}
F0R(i, n) {
F0R(j, MX) {
if (!(a[i]&(1<<j))) {
if (left[j].f == -1) left[j].f = i;
else if (left[j].s == -1) left[j].s = i;
}
}
}
F0Rd(i, n) {
F0R(j, MX) {
if (!(a[i]&(1<<j))) {
if (right[j].f == -1) right[j].f = i;
else if (right[j].s == -1) right[j].s = i;
}
}
}
// ok, get all n*MX things to swap
set<pi> swaps;
swaps.insert({0, 0}); // do nothing
F0R(i, MX) {
if (left[i].s == -1) continue; // we always get this bit
FOR(j, left[i].f+1, n-1) {
if (a[j]&(1<<i)) swaps.insert({left[i].f, j});
}
FOR(j, 0, right[i].f-1) {
if (a[j]&(1<<i)) swaps.insert({j, right[i].f});
}
}
int ans = 0;
trav(p, swaps) {
// we are swapping p.f and p.s
dbg("swapping", p.f, p.s);
swap(a[p.f], a[p.s]);
int cur = 0;
set<int> alive; F0R(i, n-1) alive.insert(i);
F0Rd(i, MX) { // see if we can get this bit
if (left[i].s == -1) { // we always get this bit
cur += (1<<i);
continue;
}
int l = n-2, r = 0;
// calculate the ok range
// find where we lose coming from the left
// it will either be left[i].f, left[i].s, p.f, p.s
if (!(a[left[i].f]&(1<<i))) ckmin(l, left[i].f-1);
if (!(a[left[i].s]&(1<<i))) ckmin(l, left[i].s-1);
if (!(a[p.f]&(1<<i))) ckmin(l, p.f-1);
if (!(a[p.s]&(1<<i))) ckmin(l, p.s-1);
// find where we lose coming from the right
// it will either be right[i].f, right[i].s, p.f, p.s
if (!(a[right[i].f]&(1<<i))) ckmax(r, right[i].f);
if (!(a[right[i].s]&(1<<i))) ckmax(r, right[i].s);
if (!(a[p.f]&(1<<i))) ckmax(r, p.f);
if (!(a[p.s]&(1<<i))) ckmax(r, p.s);
dbg(i, l, r);
set<int> nxt;
trav(x, alive) if (x <= l || x >= r) nxt.insert(x);
if (sz(nxt)) {
cur += (1<<i);
alive = nxt;
}
}
ckmax(ans, cur);
swap(a[p.f], a[p.s]); // undo
}
cout << ans << nl;
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3528kb
input:
3 6 6 5 4 3 5 6 6 1 2 1 1 2 2 5 1 1 2 2 2
output:
7 3 3
result:
ok 3 number(s): "7 3 3"
Test #2:
score: -100
Time Limit Exceeded
input:
1000 100 803046221 177233942 164782937 53823867 383853667 250036100 888743479 576687945 737272231 801579441 647643785 393059353 401516062 663466861 308544510 825328494 162739603 501761995 570908380 655227403 444493122 844535039 208303132 493226172 421479971 634680694 396627047 787471115 335787136 16...