結果
| 問題 |
No.2325 Skill Tree
|
| コンテスト | |
| ユーザー |
Luke02561
|
| 提出日時 | 2023-05-28 17:34:37 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 757 ms / 3,000 ms |
| コード長 | 7,126 bytes |
| コンパイル時間 | 4,870 ms |
| コンパイル使用メモリ | 289,584 KB |
| 実行使用メモリ | 25,132 KB |
| 最終ジャッジ日時 | 2024-12-27 13:05:19 |
| 合計ジャッジ時間 | 28,282 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 36 |
ソースコード
#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))
using namespace std;
using ll = long long;
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<typename T>
struct SegTree{
ll n;T e;vector<T>tree;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);}
void update(ll idx,T x){idx+=n-1;tree[idx]=add(x,tree[idx]);while(idx){idx=(idx-1)/2;tree[idx]=f(tree[idx*2+1],tree[idx*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){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); };
bool inrange(const Vector2D a, const Vector2D b) { return (InRange(x, a.x, b.x) and InRange(y, a.y, b.y)); }
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.y+y*a.x; }
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; }
// MAIN PROGRAM ------------
using mint = modint<MOD2>;
using Vec2 = Vector2D<ll>;
const Vec2 Angle[] = {{0,1}, {0,-1}, {-1,0}, {1,0}};
int main() {
ll n;
cin >> n;
vector<Vec2>a(n);
vector<vector<Vec2>>G(n);
rep(i, n) {
if (!i) continue;
cin >> a[i].x >> a[i].y;
--a[i].y;
G[a[i].y].push_back({a[i].x, i});
}
vector<ll>cost(n, INF);
cost[0] = 0;
p_que<Vec2>que;
que.push({0, 0});
while(que.size()) {
auto [c, now] = que.top(); que.pop();
if (c!=cost[now]) continue;
for (auto [i,j] : G[now]) {
if (chmin(cost[j], max(i, cost[now]))) {
que.push({cost[j], j});
}
}
}
vector<ll>levs;
map<ll,ll>linv;
SegTree<ll>seg(n, [](ll a,ll b){return a+b;}, 0ll, [](ll nxt,ll old){return nxt+old;});
{
vector<ll>tmp;
rep(i, n) {
tmp.push_back(cost[i]);
}
sort(ALL(tmp));
tmp.erase(unique(ALL(tmp)), tmp.end());
levs = tmp;
rep(i, levs.size()) {
linv[levs[i]] = i;
}
rep(i, n) {
seg.update(linv[cost[i]], 1);
}
}
// for (auto i : levs) {
// cout << i << " ";
// }
// cout << endl;
// rep(i, n) cout << seg.get(i) << " ";
// cout << endl;
ll q;
cin >> q;
rep(idx, q) {
ll t,x;
cin >> t >> x;
if (t == 1) {
auto itr = lower_bound(ALL(levs), x);
if (*itr!=x) --itr;
ll i = itr-levs.begin();
// cout << i << " ";
cout << seg.query(0, i+1) << endl;
}
else {
if (cost[x-1]==INF) cout << -1 << endl;
else cout << cost[x-1] << endl;
}
}
}
Luke02561