結果

問題 No.2740 Old Maid
ユーザー Luke02561
提出日時 2024-04-20 15:43:00
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 107 ms / 2,000 ms
コード長 8,077 bytes
コンパイル時間 4,464 ms
コンパイル使用メモリ 270,920 KB
実行使用メモリ 13,400 KB
最終ジャッジ日時 2024-10-12 11:24:52
合計ジャッジ時間 10,790 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 62
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define rep(i,n) for(ll i=0;i<(n);++i)
#define ALL(x) x.begin(),x.end()
#define BACK(x) x.rbegin(),x.rend()
#define MOD1 1000000007
#define MOD2 998244353
#define MOD1_BASE 131
#define INF (LLONG_MAX / 2)
#define FLOAT_ANS setprecision(30)
#define TORAD(x) (x*acos(-1)/180.0)
#define TODEG(x) (x*180/acos(-1))
#define GET_VALUENAME(value) # value
using namespace std;
using ll = long long;
using LL = __int128_t;
using ull = unsigned long long;
template<typename T> // T:
using p_que = priority_queue<T,vector<T>,greater<T>>;
template<typename T>
bool chmin(T& a,T b){if(a>b){a=b;return true;}return false;}
template<typename T>
bool chmax(T& a,T b){if(a<b){a=b;return true;}return false;}
ll modpow(ll a, ll n, ll mod) {ll res=1;while (n>0) {if(n&1)res=(res*(a%mod))%mod;a=((a%mod)*(a%mod))%mod;n>>=1;}return res;}
template<typename T>
void RotateVec2(vector<vector<T>>&v){ll h=v.size();ll w=v[0].size();vector<vector<T>>t(w,vector<T>(h));rep(i,h){rep(j,w){t[j][h-i-1]=v[i][j];}}v=t;}
template<class T>
bool InRange(T x, T mn, T mx){return (mn <= x && x <= mx);}
template<typename T>
vector<T>&merged(vector<T>&a,vector<T>&b) {vector<T>res;merge(a.begin(),a.end(),b.begin(),b.end(),back_inserter(res));return res;}
struct UnionFind{
vector<ll>tree;
UnionFind(ll x):tree(x, -1){}
ll root(ll x){if(tree[x]<0) return x;return tree[x]=root(tree[x]);}
bool same(ll x,ll y){return root(x)==root(y);}
ll size(ll x){return -tree[root(x)];}
void unite(ll x,ll y){x=root(x),y=root(y);if(x==y)return;if(size(x)<size(y))swap(x,y);tree[x]+=tree[y];tree[y]=x;}
};
template<class T>
struct SegTree{
ll n;T e;vector<T>tree,lazy;function<T(T,T)>f,add;
SegTree(ll n_,function<T(T,T)>f_,T e_=0,function<T(T,T)>add_=[](T next,T old){return next;}):e(e_),f(f_),add(add_){
ll x=1;
while(x<n_)x*=2;
n=x;
tree.assign(n*2,e);
lazy.assign(n*2,e);
}
void eval(T k) {
if (lazy[k] == e) return;
if (k < n-1){
lazy[k*2+1]=lazy[k*2+1]=lazy[k];
}
tree[k]=lazy[k], lazy[k]=e;
}
void update(ll idx,T x){
update(idx, idx+1, x);
}
void update(ll a, ll b, ll x) { update(a, b, x, 0, n, 0); }
void update(ll a, ll b, ll x, ll l, ll r, ll k) {
eval(k);
if (a <= l and r <= b) {
lazy[k] = x;
eval(k);
}
else if (a < r and l < b) {
update(a, b, x, l, (l+r)/2, k*2+1);
update(a, b, x, (l+r)/2, r, k*2+1);
tree[k] = f(tree[k*2+1], tree[k*2+2]);
}
}
T query(ll x,ll y){
return query_sub(x,y,0,n,0);
}
T query_sub(ll x,ll y,ll l,ll r,ll k){
eval(k);
if(r<=x||y<=l)return e;
if(x<=l&&r<=y)return tree[k];
T c1=query_sub(x,y,l,(l+r)/2,k*2+1);
T c2=query_sub(x,y,(l+r)/2,r,k*2+2);
return f(c1,c2);
}
T get(ll idx){return tree[idx+n-1];}
};
template<std::uint_fast64_t Modulus> class modint {
using u64 = std::uint_fast64_t;
public:
u64 a;
constexpr modint(const u64 x = 0) noexcept : a(((x % Modulus)+Modulus)%Modulus) {}
constexpr u64 &value() noexcept { return a; }
constexpr const u64 &value() const noexcept { return a; }
constexpr modint operator+(const modint rhs) const noexcept {return modint(*this) += rhs;}
constexpr modint operator-(const modint rhs) const noexcept {return modint(*this) -= rhs;}
constexpr modint operator*(const modint rhs) const noexcept {return modint(*this) *= rhs;}
constexpr modint operator/(const modint rhs) const noexcept {return modint(*this) /= rhs;}
constexpr modint &operator+=(const modint rhs) noexcept {a += rhs.a;if (a >= Modulus) {a -= Modulus;}return *this;}
constexpr modint &operator-=(const modint rhs) noexcept {if (a < rhs.a) {a += Modulus;}a -= rhs.a;return *this;}
constexpr modint &operator*=(const modint rhs) noexcept {a = a * rhs.a % Modulus;return *this;}
constexpr modint &operator/=(modint rhs) noexcept {
u64 exp = Modulus - 2;
while (exp) {
if (exp % 2) {
*this *= rhs;
}
rhs *= rhs;
exp /= 2;
}
return *this;
}
constexpr modint &operator=(u64 x){ a = x % Modulus; return *this; }
};
template<class T=ll>
struct Vector2D {
T x, y;
Vector2D():x(0),y(0) {}
Vector2D(T x_, T y_):x(x_),y(y_) {}
double length() const { return sqrt((double)x*x+y*y); };
T lengthp() const { return x*x+y*y; };
bool inrange(const Vector2D a, const Vector2D b) { return (InRange(x, a.x, b.x) and InRange(y, a.y, b.y)); }
Vector2D yx() { return Vector2D{ y, x }; }
Vector2D operator-(const Vector2D a) const { return Vector2D(*this) -= a; }
Vector2D operator+(const Vector2D a) const { return Vector2D(*this) += a; }
T operator*(const Vector2D a) const { return x*a.x+y*a.y; }
Vector2D operator*(const T a) const { return Vector2D(*this) *= a; }
Vector2D operator/(const T a) const { return Vector2D(*this) /= a; }
Vector2D &operator+=(const Vector2D a) { x += a.x; y += a.y; return *this; }
Vector2D &operator-=(const Vector2D a) { x -= a.x; y -= a.y; return *this; }
Vector2D &operator-=(const T a) { x -= a; y -= a; return *this; }
Vector2D &operator*=(const T a) { x *= a; y *= a; return *this; }
Vector2D &operator/=(const T a) { x /= a; y /= a; return *this; }
friend ostream& operator<< (ostream& stream, const Vector2D<>& x);
bool operator==(const Vector2D a) const { return (x==a.x and y==a.y); }
bool operator!=(const Vector2D a) const { return not (x==a.x and y==a.y); }
bool operator>(const Vector2D a) const { return a < *this; }
bool operator<(const Vector2D a) const
{
return make_pair(x,y) < make_pair(a.x, a.y);
// return x*a.y < y*a.x;
}
};
ostream& operator<< (ostream& stream, const Vector2D<ll>& x) {
string s = "(" + to_string(x.x) + ", " + to_string(x.y) + ")";
stream << s;
return stream;
}
ll popcount(ll x) { ll res = 0; while(x) {res+=x%2;x>>=1;} return res; }
// debug kit
void print() { cout << endl; }
template<class T>
void print_(vector<T>x) { for(auto i : x) cout << i << " "; }
template<class T>
void print_(T x) { cout << x << " "; }
#ifdef ONLINE_JUDGE
template<class T, class ...Args>
void print(T head, Args... args) {}
template<class T>
void debug(T value) {}
#else
template<class T, class ...Args>
void print(T head, Args... args) { print_(head); print(args...); }
template<class T>
void debug(T value) { print((string)"\""+GET_VALUENAME(value)+"\": ", value); }
#endif
// MAIN PROGRAM ------------
using mint = modint<MOD2>;
using Vec2 = Vector2D<ll>;
const Vec2 Angle[] = {{0,1}, {0,-1}, {-1,0}, {1,0}};
struct Node
{
ll prev, next, value;
bool valid = true;
};
int main() {
ll n;
cin >> n;
vector<Node>p(n+2);
vector<ll>inv(n);
rep(i, n) {
cin >> p[i].value;
--p[i].value;
p[i].next = i+1;
p[i].prev = i-1;
inv[p[i].value] = i;
}
p[0].prev = n+1;
vector<ll>q;
function<ll(ll)>getNext = [&](ll i)
{
ll next = p[i].next;
if (p[next].valid) return next;
return p[i].next = getNext(p[i].next);
};
function<ll(ll)>getPrev = [&](ll i)
{
ll prev = p[i].prev;
if (p[prev].valid) return prev;
return p[i].prev = getPrev(p[i].prev);
};
// for (auto i : p) cout << i.value << " ";
rep(i, n) {
ll idx = inv[i];
if (not p[inv[i]].valid) continue;
if (getNext(idx) == n) continue;
// cout << i + 1 << " " << inv[i] << endl;
Node &x = p[idx], &y = p[getNext(idx)];
Node &prev = p[getPrev(idx)], &next = p[getNext(getNext(idx))];
x.valid = y.valid = false;
q.push_back(x.value+1);
q.push_back(y.value+1);
prev.next = y.next;
next.prev = x.prev;
}
for (auto i : q) cout << i << " ";
cout << endl;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0