結果
問題 | No.1230 Hall_and_me |
ユーザー |
![]() |
提出日時 | 2020-09-18 21:30:30 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 2 ms / 2,000 ms |
コード長 | 16,861 bytes |
コンパイル時間 | 1,888 ms |
コンパイル使用メモリ | 185,376 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-06-22 08:59:19 |
合計ジャッジ時間 | 2,824 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 36 |
ソースコード
#ifndef ONLINE_JUDGE#define _GLIBCXX_DEBUG#endif#include<bits/stdc++.h>using namespace std;#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)#define bit(n,k) (((ll)n>>(ll)k)&1) /*nのk bit目*/#define pb push_back#define pf push_front#define FI first#define SE second#define eb emplace_back#define SZ(x) ((ll)(x).size())#define all(x) (x).begin(),(x).end()#define rall(x) (x).rbegin(),(x).rend()#define PI 3.14159265359const double eps = 1e-12;const long long INF= 1e+18+1;//long long INF=(1LL<<31)-1;typedef long long ll;typedef vector<ll> vl;typedef vector<vector<ll> >vvl;typedef pair<ll,ll> P;typedef tuple<ll,ll,ll> T;typedef struct Point_Coordinates {ll x, y;} point;const ll MOD=1000000007LL;//ll MOD=1000000007LL;//const ll MOD=998244353LL;//const ll MOD=1777777777LL;//const ll MAX_V=114514LL;//const ll MAX = 500010LL;const ll mod=MOD;string abc="abcdefghijklmnopqrstuvwxyz";string ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ";vl dx={0,0,1,-1};vl dy={1,-1,0,0};/*struct edge{ll from;ll to;ll cost;};*///素因数分解O(√n)map<ll,ll>prime_factor(ll n){map<ll,ll>res;for(ll i=2;i*i<=n;i++){while(n%i==0){res[i]++;n/=i;}}if(n!=1)res[n]=1;return res;}const ll MAX = 2000010;long long fac[MAX], finv[MAX], inv[MAX];//finvが階乗の逆元// テーブルを作る前処理void COMinit() {fac[0] = fac[1] = 1;finv[0] = finv[1] = 1;inv[1] = 1;for (ll i = 2; i < MAX; i++){fac[i] = fac[i - 1] * i % MOD;inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;finv[i] = finv[i - 1] * inv[i] % MOD;}}// 二項係数計算long long COM(ll n, ll k){if (n < k) return 0;if (n < 0 || k < 0) return 0;return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;}ll modpow(ll a, ll n) {ll res = 1;while (n > 0) {if (n & 1) res = res * a % mod;a = a * a % mod;n >>= 1;}return res;}/*Eratosthenes()ll N=2000010;vl arr(N);void Eratosthenes(){for(ll i = 0; i < N; i++){arr[i] = 1;}arr[1]=0;for(ll i = 2; i < sqrt(N); i++){if(arr[i]){for(ll j = 0; i * (j + 2) < N; j++){arr[i *(j + 2)] = 0;}}}}*///素数判定O(√n)bool is_prime(ll n){for(ll i=2;i*i<=n;i++){if(n%i==0)return false;}return n!=1;}//約数の列挙O(√n)vector<ll>divisor(ll n){vector<ll>res;for(ll i=1;i*i<=n;i++){if(n%i==0){res.push_back(i);if(i != n/i) res.push_back(n/i);}}return res;}/* SegTree<X>(n,fx,ex): モノイド(集合X, 二項演算fx, 単位元ex)についてサイズnで構築set(int i, X x), build(): i番目の要素をxにセット。まとめてセグ木を構築する。O(n)update(i,x): i 番目の要素を x に更新。O(log(n))query(a,b): [a,b) 全てにfxを作用させた値を取得。O(log(n))*/template <typename X>struct SegTree {using FX = function<X(X, X)>;int n;FX fx;const X ex;vector<X> dat;SegTree(int n_, FX fx_, X ex_) : n(), fx(fx_), ex(ex_), dat(n_ * 4, ex_) {int x = 1;while (n_ > x) {x *= 2;}n = x;}void set(int i, X x) { dat[i + n - 1] = x; }void build() {for (int k = n - 2; k >= 0; k--) dat[k] = fx(dat[2 * k + 1], dat[2 * k + 2]);}void update(int i, X x) {i += n - 1;dat[i] = x;while (i > 0) {i = (i - 1) / 2; // parentdat[i] = fx(dat[i * 2 + 1], dat[i * 2 + 2]);}}// the minimum element of [a,b)X query(int a, int b) { return query_sub(a, b, 0, 0, n); }X query_sub(int a, int b, int k, int l, int r) {if (r <= a || b <= l) {return ex;} else if (a <= l && r <= b) {return dat[k];} else {X vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);X vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);return fx(vl, vr);}}/* debug */inline X operator[](int a) { return query(a, a + 1); }void print() {for (int i = 0; i < 2 * n - 1; ++i) {cout << (*this)[i];if (i != n) cout << ",";}cout << endl;}/*使用例auto fx=[](int x1,int x2)->int{return max(x1,x2);};ll ex=0;SegTree<ll>rmq(n,fx,ex);*/};/* Trie 木: 文字の種類(char_size)、int型で0に対応する文字(base)insert(word): 単語 word を Trie 木に挿入するsearch(word): 単語 word が Trie 木にあるか判定するstart_with(prefix): prefix が一致する単語が Trie 木にあるか判定するcount(): 挿入した単語の数を返すsize(): Trie 木の頂点数を返す計算量:insert, search ともに O(M)(Mは単語の長さ)*/template <int char_size, int base>struct Trie {struct Node { // 頂点を表す構造体vector<int> next; // 子の頂点番号を格納。存在しなければ-1vector<int> accept; // 末端がこの頂点になる単語の word_id を保存int c; // base からの間隔をint型で表現したものint common; // いくつの単語がこの頂点を共有しているかNode(int c_) : c(c_), common(0) {next.assign(char_size, -1);}};vector<Node> nodes; // trie 木本体int root;Trie() : root(0) {nodes.push_back(Node(root));}// 単語の挿入void insert(const string &word, int word_id) {int node_id = 0;for (int i = 0; i < (int)word.size(); i++) {int c = (int)(word[i] - base);int &next_id = nodes[node_id].next[c];if (next_id == -1) { // 次の頂点が存在しなければ追加next_id = (int)nodes.size();nodes.push_back(Node(c));}++nodes[node_id].common;node_id = next_id;}++nodes[node_id].common;nodes[node_id].accept.push_back(word_id);}void insert(const string &word) {insert(word, nodes[0].common);}// 単語とprefixの検索bool search(const string &word, bool prefix = false) {int node_id = 0;for (int i = 0; i < (int)word.size(); i++) {int c = (int)(word[i] - base);int &next_id = nodes[node_id].next[c];if (next_id == -1) { // 次の頂点が存在しなければ終了return false;}node_id = next_id;}return (prefix) ? true : nodes[node_id].accept.size() > 0;}// prefix を持つ単語が存在するかの検索bool start_with(const string &prefix) {return search(prefix, true);}// 挿入した単語の数int count() const {return (nodes[0].common);}// Trie木のノード数int size() const {return ((int)nodes.size());}};// union by size + path havingclass UnionFind {public:vector <ll> par; // 各元の親を表す配列vector <ll> siz; // 素集合のサイズを表す配列(1 で初期化)// ConstructorUnionFind(ll sz_): par(sz_), siz(sz_, 1LL) {for (ll i = 0; i < sz_; ++i) par[i] = i; // 初期では親は自分自身}void init(ll sz_) {par.resize(sz_);siz.assign(sz_, 1LL); // resize だとなぜか初期化されなかったfor (ll i = 0; i < sz_; ++i) par[i] = i; // 初期では親は自分自身}// Member Function// Findll root(ll x) { // 根の検索while (par[x] != x) {x = par[x] = par[par[x]]; // x の親の親を x の親とする}return x;}// Union(Unite, Merge)bool merge(ll x, ll y) {x = root(x);y = root(y);if (x == y) return false;// merge technique(データ構造をマージするテク.小を大にくっつける)if (siz[x] < siz[y]) swap(x, y);siz[x] += siz[y];par[y] = x;return true;}bool issame(ll x, ll y) { // 連結判定return root(x) == root(y);}ll size(ll x) { // 素集合のサイズreturn siz[root(x)];}};// 0-indexed parmutation onlyvvl cycle_partition(const vl &p){ll n=p.size();vvl ret;vector<bool> check(n,false);rep(i,n)if(!check[p[i]]){vl v;ll pos=p[i];v.pb(i);check[i]=true;while(pos!=i){v.pb(pos);check[pos]=true;pos=p[pos];}ret.pb(v);}return ret;}//Manachar 修理中// vl Manachar(string S){// ll c=0,n=S.size();// vl R(n,1);// for(ll i=0;i<n;i++){// ll l=c-(i-c);// if(i+R[l]<c+R[c]){// R[i]=R[l];// }else{// ll j=c+R[c]-i;// while(i-j>=0 && i+j<n && S[i-j] == S[i+j])j++;// R[i]=j;// c=i;// }// }// return R;// }template <typename T>T pow(T a, long long n, T e = 1) {T ret = e;while (n) {if (n & 1) ret *= a;a *= a;n >>= 1;}return ret;}template <int mod>struct ModInt {int x;ModInt() : x(0) {}ModInt(long long x_) {if ((x = x_ % mod + mod) >= mod) x -= mod;}ModInt& operator+=(ModInt rhs) {if ((x += rhs.x) >= mod) x -= mod;return *this;}ModInt& operator-=(ModInt rhs) {if ((x -= rhs.x) < 0) x += mod;return *this;}ModInt& operator*=(ModInt rhs) {x = (unsigned long long)x * rhs.x % mod;return *this;}ModInt& operator/=(ModInt rhs) {x = (unsigned long long)x * rhs.inv().x % mod;return *this;}ModInt operator-() const { return -x < 0 ? mod - x : -x; }ModInt operator+(ModInt rhs) const { return ModInt(*this) += rhs; }ModInt operator-(ModInt rhs) const { return ModInt(*this) -= rhs; }ModInt operator*(ModInt rhs) const { return ModInt(*this) *= rhs; }ModInt operator/(ModInt rhs) const { return ModInt(*this) /= rhs; }bool operator==(ModInt rhs) const { return x == rhs.x; }bool operator!=(ModInt rhs) const { return x != rhs.x; }ModInt inv() const { return pow(*this, mod - 2); }friend ostream& operator<<(ostream& s, ModInt<mod> a) {s << a.x;return s;}friend istream& operator>>(istream& s, ModInt<mod>& a) {s >> a.x;return s;}};using mint = ModInt<MOD>;/* RMQ:[0,n-1] について、区間ごとの最小値を管理する構造体update(a,b,x): 区間[a,b) の要素を x に更新。O(log(n))query(a,b): [a,b) での最小の要素を取得。O(log(n))*/template <typename T>struct RMQ {//const T INF = numeric_limits<T>::max();int n;vector<T> dat, lazy;RMQ(int n_) : n(), dat(n_ * 4, INF), lazy(n_ * 4, INF) {int x = 1;while (n_ > x) x *= 2;n = x;}/* lazy eval */void eval(int k) {if (lazy[k] == INF) return; // 更新するものが無ければ終了if (k < n - 1) { // 葉でなければ子に伝搬lazy[k * 2 + 1] = lazy[k];lazy[k * 2 + 2] = lazy[k];}// 自身を更新dat[k] = lazy[k];lazy[k] = INF;}void update(int a, int b, T x, int k, int l, int r) {eval(k);if (a <= l && r <= b) { // 完全に内側の時lazy[k] = x;eval(k);} else if (a < r && l < b) { // 一部区間が被る時update(a, b, x, k * 2 + 1, l, (l + r) / 2); // 左の子update(a, b, x, k * 2 + 2, (l + r) / 2, r); // 右の子dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);}}void update(int a, int b, T x) { update(a, b, x, 0, 0, n); }T query_sub(int a, int b, int k, int l, int r) {eval(k);if (r <= a || b <= l) { // 完全に外側の時return INF;} else if (a <= l && r <= b) { // 完全に内側の時return dat[k];} else { // 一部区間が被る時T vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);T vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);return min(vl, vr);}}T query(int a, int b) { return query_sub(a, b, 0, 0, n); }/* debug */inline T operator[](int a) { return query(a, a + 1); }void print() {for (int i = 0; i < 2 * n - 1; ++i) {cout << (*this)[i];if (i != n) cout << ",";}cout << endl;}};// aよりもbが大きいならばaをbで更新する// (更新されたならばtrueを返す)template <typename T>bool chmax(T &a, const T& b) {if (a < b) {a = b; // aをbで更新return true;}return false;}// aよりもbが小さいならばaをbで更新する// (更新されたならばtrueを返す)template <typename T>bool chmin(T &a, const T& b) {if (a > b) {a = b; // aをbで更新return true;}return false;}/* BIT: RAQ対応BIT初期値は a_1 = a_2 = ... = a_n = 0 1-Indexedに注意!!!!!!!!・add(l,r,x): [l,r) に x を加算する・sum(i): a_1 + a_2 + ... + a_i を計算する query(l,r)で[l,r)の総和出力計算量は全て O(logn)*/template <typename T>struct BIT {int n; // 要素数vector<T> bit[2]; // データの格納先BIT(int n_) { init(n_); }void init(int n_) {n = n_ + 1;for (int p = 0; p < 2; p++) bit[p].assign(n, 0);}void add_sub(int p, int i, T x) {for (int idx = i; idx < n; idx += (idx & -idx)) {bit[p][idx] += x;}}void add(int l, int r, T x) { // [l,r) に加算add_sub(0, l, -x * (l - 1));add_sub(0, r, x * (r - 1));add_sub(1, l, x);add_sub(1, r, -x);}T sum_sub(int p, int i) {T s(0);for (int idx = i; idx > 0; idx -= (idx & -idx)) {s += bit[p][idx];}return s;}T sum(int i) { return sum_sub(0, i) + sum_sub(1, i) * i; }// [l,r) の区間和を取得T query(int l, int r) { return sum(r - 1) - sum(l - 1); }};/*struct Edge {long long to;};using Graph = vector<vector<Edge>>;*//* LCA(G, root): 木 G に対する根を root として Lowest Common Ancestor を求める構造体query(u,v): u と v の LCA を求める。計算量 O(logn)前処理: O(nlogn)時間, O(nlogn)空間*//*struct LCA {vector<vector<int>> parent; // parent[k][u]:= u の 2^k 先の親vector<int> dist; // root からの距離LCA(const Graph &G, int root = 0) { init(G, root); }// 初期化void init(const Graph &G, int root = 0) {int V = G.size();int K = 1;while ((1 << K) < V) K++;parent.assign(K, vector<int>(V, -1));dist.assign(V, -1);dfs(G, root, -1, 0);for (int k = 0; k + 1 < K; k++) {for (int v = 0; v < V; v++) {if (parent[k][v] < 0) {parent[k + 1][v] = -1;} else {parent[k + 1][v] = parent[k][parent[k][v]];}}}}// 根からの距離と1つ先の頂点を求めるvoid dfs(const Graph &G, int v, int p, int d) {parent[0][v] = p;dist[v] = d;for (auto e : G[v]) {if (e.to != p) dfs(G, e.to, v, d + 1);}}int query(int u, int v) {if (dist[u] < dist[v]) swap(u, v); // u の方が深いとするint K = parent.size();// LCA までの距離を同じにするfor (int k = 0; k < K; k++) {if ((dist[u] - dist[v]) >> k & 1) {u = parent[k][u];}}// 二分探索で LCA を求めるif (u == v) return u;for (int k = K - 1; k >= 0; k--) {if (parent[k][u] != parent[k][v]) {u = parent[k][u];v = parent[k][v];}}return parent[0][u];}int get_dist(int u, int v) { return dist[u] + dist[v] - 2 * dist[query(u, v)]; }bool is_on_path(int u, int v, int a) { return get_dist(u, a) + get_dist(a, v) == get_dist(u, v); }};*/int main(){ios::sync_with_stdio(false);std::cin.tie(nullptr);cout << fixed << setprecision(10);/*--------------------------------*/double p,q,r;cin>>p>>q>>r;cout<<(p+q+r-min({p,q,r}))/(p+q+r)<<endl;}