#include
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void put(T x)
{
if (x > 9)
put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void _put(T x)
{
if (x < 0)
x = -x, putchar('-');
put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
using std::set;
using std::map;
using std::pair;
using std::string;
using std::vector;
using std::multiset;
using std::priority_queue;
typedef long long ll;
typedef long double ld;
typedef set<int>::iterator it;
const int Maxn = 1e9;
const int N = 2e5 + 5;
int n, top, T_data;
set<int> out[N];
int ind[N], pre[N], stk[N], sze[N], fa[N];
inline int ufs_find(int x)
{
if (fa[x] != x)
return fa[x] = ufs_find(fa[x]);
return x;
}
inline void Merge(int x, int y)
{
int tx = ufs_find(x),
ty = ufs_find(y);
if (tx == ty)
return ;
if (out[tx].size() < out[ty].size())
std::swap(tx, ty);
fa[ty] = tx;
sze[tx] += sze[ty];
for (it e2 = out[ty].begin(); e2 != out[ty].end(); ++e2)
{
y = *e2;
it e1 = out[tx].find(y);
if (e1 == out[tx].end())
out[tx].insert(y);
else
{
--ind[y];
if (ind[y] == 1)
stk[++top] = y;
}
}
}
int main()
{
read(T_data);
for (int t = 1; t <= T_data; ++t)
{
read(n);
top = 0;
for (int i = 1; i <= n; ++i)
{
out[i].clear();
fa[i] = i;
sze[i] = 1;
}
for (int i = 1, x; i <= n; ++i)
{
read(ind[i]);
for (int j = 1; j <= ind[i]; ++j)
{
read(x);
out[x].insert(i);
}
pre[i] = x;
if (ind[i] == 1)
stk[++top] = i;
}
while (top)
{
int x = stk[top--];
Merge(pre[x], x);
}
int ans = 0;
for (int i = 1; i <= n; ++i)
if (ufs_find(i) == i)
CkMax(ans, sze[i]);
printf("Case #%d: %d\n", t, ans);
}
return 0;
}
#include
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void put(T x)
{
if (x > 9)
put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void _put(T x)
{
if (x < 0)
x = -x, putchar('-');
put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
using std::set;
using std::map;
using std::pair;
using std::string;
using std::vector;
using std::multiset;
using std::priority_queue;
typedef long long ll;
typedef long double ld;
const int mod = 998244353;
const int Maxn = 1e9;
const int N = 2e5 + 5;
int T_data, n, qr;
int que[N], p[N], ind[N], _ind[N];
vector<int> e[N];
bool inv[N], vis[N];
inline void add(int &x, int y)
{
x += y;
x >= mod ? x -= mod : 0;
}
inline void dec(int &x, int y)
{
x -= y;
x < 0 ? x += mod : 0;
}
int main()
{
srand(time(0));
read(T_data);
for (int t = 1; t <= T_data; ++t)
{
read(n);
for (int i = 1; i <= n; ++i)
{
vis[i] = inv[i] = false;
e[i].clear();
}
for (int i = 1; i <= n; ++i)
{
read(ind[i]);
_ind[i] = ind[i];
for (int j = 1, x; j <= ind[i]; ++j)
{
read(x);
e[x].push_back(i);
}
}
for (int i = 1; i <= n; ++i)
p[i] = i;
std::random_shuffle(p + 1, p + n + 1);
int ans = 0;
for (int i = 1; i <= n; ++i)
if (!inv[p[i]])
{
que[qr = 1] = p[i];
inv[p[i]] = vis[p[i]] = true;
for (int j = 1, x; j <= qr; ++j)
{
x = que[j];
for (int y : e[x])
{
if (vis[y])
continue ;
if (!--ind[y])
{
que[++qr] = y;
inv[y] = vis[y] = true;
}
}
}
for (int j = 1, x, y; j <= qr; ++j)
{
vis[x = que[j]] = false;
for (int y : e[x])
ind[y] = _ind[y];
}
CkMax(ans, qr);
}
printf("Case #%d: %d\n", t, ans);
}
return 0;
}
n n n 个人坐电梯,楼共 k k k 层,每人有起始楼层和目标楼层。
电梯有载客量限制 m m m,上升时可以上升到任意层并随时下降,但是下降要一直下降到一层才能才能再上升。
电梯每秒运行一层,忽略换方向和上下人的时间,问电梯最短运行时间。
n , m ≤ 2 × 1 0 5 , k ≤ 1 0 9 n,m\le 2\times 10^5, k\le 10^9 n,m≤2×105,k≤109
将每个人视作一条线段 [ l , r ] [l, r] [l,r],不难发现,每趟乘电梯向上和向下的人需要分开处理,但其问题本质相同。
考虑直接贪心,显然每趟从一层出发并回到一层都要取当前 r r r 最大的人,即在需要乘电梯向上和向下的人取最大的 r r r 计入答案,运行过程中我们需要尽可能往电梯中塞人。
实际上塞人的过程也是在贪心取 r r r 最大的人,只是需要考虑载客量的限制,每次取的 r r r 一定单调不增。
对于当前高度(当前在乘电梯的人中最小的 r r r,记作 r min r_{\min} rmin),我们用两个 set
分别维护电梯中的人和还未乘电梯的人。
若电梯中的人数 < m
若电梯中的人数 = m = m =m,我们需要在还未乘电梯的人中找到 r r r 最大且 r ≤ l max r \le l_{\max} r≤lmax 的人,即强制使至少一人走出电梯。
每次更新 r min r_{\min} rmin 将需要走出电梯的人在对应的 set
中删除。
这样我们每次操作都能使一人乘上电梯,总时间复杂度 O ( n log n ) \mathcal O(n\log n) O(nlogn)。
#include
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void put(T x)
{
if (x > 9)
put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void _put(T x)
{
if (x < 0)
x = -x, putchar('-');
put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
using std::set;
using std::map;
using std::pair;
using std::string;
using std::vector;
using std::multiset;
using std::priority_queue;
typedef long long ll;
typedef long double ld;
const ld pi = acos(-1.0);
const ld eps = 1e-8;
const int N = 4e5 + 5;
const int Maxn = 1e9;
int n, m, k; ll ans;
int a[N], b[N];
struct point
{
int v, i;
point() {}
point(int V, int I):
v(V), i(I) {}
inline bool operator < (const point &a) const
{
return v > a.v || v == a.v && i < a.i;
}
};
set<point> peo[2], elv[2];
typedef set<point>::iterator it;
inline int solve(int t)
{
if (peo[t].begin() == peo[t].end())
return 0;
int cnt = 0, h = peo[t].begin()->v,
now = k;
while (1)
{
it e = peo[t].lower_bound(point(cnt < m ? now : elv[t].begin()->v, 0));
if (e == peo[t].end())
return h;
elv[t].insert(point(b[e->i], e->i));
now = a[e->i];
peo[t].erase(e);
++cnt, --n;
while (elv[t].begin()->v >= now)
elv[t].erase(elv[t].begin()), --cnt;
}
return h;
}
int main()
{
read(n); read(m); read(k);
for (int i = 1; i <= n; ++i)
{
read(a[i]);
read(b[i]);
if (a[i] > b[i])
peo[0].insert(point(a[i], i));
else
{
std::swap(a[i], b[i]);
peo[1].insert(point(a[i], i));
}
}
while (n)
{
int h1 = solve(0),
h2 = solve(1);
ans += 2ll * (Max(h1, h2) - 1);
}
std::cout << ans << std::endl;
return 0;
}
证明 设点 x x x 的度为 d e g x deg_x degx,第一次游走到其父结点的期望步数为 f x f_x fx。
- 若 x x x 为叶子结点,显然 f x = 1 = 2 s i z e x − 1 f_x = 1 = 2size_x - 1 fx=1=2sizex−1。
- 若 x x x 不为叶子结点,设其子结点为 y 1 , y 2 , … , y k y_1, y_2, \dots, y_k y1,y2,…,yk, ∀ 1 ≤ i ≤ k , f y i = 2 s i z e y i − 1 \forall 1 \le i \le k, f_{y_i} = 2size_{y_i} - 1 ∀1≤i≤k,fyi=2sizeyi−1,则
f x = 1 + ∑ i = 1 k ( f y i + f x ) d e g x f x = d e g x + ∑ i = 1 k f y i = 2 ( ∑ i = 1 k s i z e y i + 1 ) − 1 = 2 s i z e x − 1 \begin{aligned}f_x &= 1 + \frac{\sum \limits_{i = 1}^{k}(f_{y_i} + f_x)}{deg_x} \\f_x &= deg_x + \sum \limits_{i = 1}^{k}f_{y_i} \\&= 2(\sum\limits_{i = 1}^{k}size_{y_i} + 1) - 1 \\& = 2size_x - 1\\\end{aligned} fxfx=1+degxi=1∑k(fyi+fx)=degx+i=1∑kfyi=2(i=1∑ksizeyi+1)−1=2sizex−1
#include
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void put(T x)
{
if (x > 9)
put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void _put(T x)
{
if (x < 0)
x = -x, putchar('-');
put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
template <class T>
inline T Sqr(T x) {return x * x;}
using std::map;
using std::set;
using std::pair;
using std::bitset;
using std::string;
using std::vector;
using std::multiset;
using std::priority_queue;
typedef long long ll;
typedef long double ld;
const ld pi = acos(-1.0);
const ld eps = 1e-8;
const int N = 1e6 + 5;
const int Maxn = 1e9;
const int mod = 998244353;
int ans, n, V, K, s;
int sze[N], fa[N], dep[N], pos[N], idx[N];
int cnt[N], fac[N], ifac[N]; bool vis[N];
vector<int> e[N];
inline void add(int &x, int y)
{
x += y;
x >= mod ? x -= mod : 0;
}
inline void dec(int &x, int y)
{
x -= y;
x < 0 ? x += mod : 0;
}
inline int quick_pow(int x, int k)
{
int res = 1;
while (k)
{
if (k & 1)
res = 1ll * res * x % mod;
x = 1ll * x * x % mod;
k >>= 1;
}
return res;
}
inline int C(int n, int m)
{
if (n < 0 || m < 0 || n < m) return 0;
return 1ll * fac[n] * ifac[n - m] % mod * ifac[m] % mod;
}
inline void addSubtree(int x, int z)
{
for (int i = pos[x]; i <= pos[x] + sze[x] - 1; ++i)
{
int y = idx[i];
add(cnt[dep[y] - dep[z]], sze[y]);
dec(cnt[dep[y] - 1], sze[y]);
}
}
inline void dfsTraverse(int x)
{
dep[x] = dep[fa[x]] + 1;
sze[x] = 1;
pos[x] = ++V;
idx[V] = x;
for (int y : e[x])
{
if (y == fa[x])
continue ;
fa[y] = x;
dfsTraverse(y);
sze[x] += sze[y];
}
}
int main()
{
read(n); read(K); read(s);
for (int i = 1, u, v; i < n; ++i)
{
read(u); read(v);
e[u].push_back(v);
e[v].push_back(u);
}
fac[0] = 1;
for (int i = 1; i <= n; ++i)
fac[i] = 1ll * fac[i - 1] * i % mod;
ifac[n] = quick_pow(fac[n], mod - 2);
for (int i = n; i >= 1; --i)
ifac[i - 1] = 1ll * i * ifac[i] % mod;
dfsTraverse(1);
while (s != 1)
{
add(ans, 2 * sze[s] - 1);
vis[s] = true;
add(cnt[1], sze[s]);
dec(cnt[dep[s] - 1], sze[s]);
for (int y : e[s])
{
if (y == fa[s] || vis[y])
continue ;
addSubtree(y, s);
}
s = fa[s];
}
for (int i = 1; i <= n - 2; ++i)
add(cnt[i], cnt[i - 1]);
int p = quick_pow(C(n - 1, K), mod - 2);
for (int i = 1; i <= n - 2; ++i)
dec(ans, 2ll * cnt[i] * p % mod * C(n - 1 - i, K - 1) % mod);
put(ans), putchar('\n');
return 0;
}
#include
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
typedef long double ld;
const int N = 1e5 + 3;
struct node
{
double pi, wi;
};
node a[N];
int n, m;
ld f[N][25];
inline bool cmp(const node &x, const node &y)
{
return x.wi + y.wi * x.pi > y.wi + x.wi * y.pi;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i)
scanf("%lf", &a[i].wi);
for(int i = 1; i <= n; ++i)
{
scanf("%lf", &a[i].pi);
a[i].pi /= 10000.0;
}
std::sort(a + 1, a + n + 1, cmp);
ld maxx = 0;
for (int i = n; i >= 1; --i)
{
for (int j = 0; j <= m; ++j)
f[i][j] = f[i + 1][j];
for (int j = 1; j <= m; ++j)
CkMax(f[i][j], f[i + 1][j - 1] * a[i].pi + a[i].wi);
}
printf("%.15lf\n", (double)f[1][m]);
return 0;
}
#include
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void put(T x)
{
if (x > 9)
put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void _put(T x)
{
if (x < 0)
x = -x, putchar('-');
put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
template <class T>
inline T Sqr(T x) {return x * x;}
using std::map;
using std::set;
using std::pair;
using std::bitset;
using std::string;
using std::vector;
using std::complex;
using std::multiset;
using std::priority_queue;
typedef long long ll;
typedef long double ld;
typedef complex<ld> com;
typedef pair<int, int> pir;
const ld pi = acos(-1.0);
const ld eps = 1e-8;
const int N = 1e7 + 5;
const int L = 5e4 + 5;
const int L4 = 2e5 + 5;
const int Maxn = 1e9;
const int Minn = -1e9;
const int mod = 998244353;
const int lim = 1e7;
int T_data, n, w, q;
int fac[N], ifac[N];
vector<int> e[12], h[12], a;
inline void add(int &x, int y)
{
x += y;
x >= mod ? x -= mod : 0;
}
inline void dec(int &x, int y)
{
x -= y;
x < 0 ? x += mod : 0;
}
inline int quick_pow(int x, int k)
{
int res = 1;
while (k)
{
if (k & 1)
res = 1ll * res * x % mod;
x = 1ll * x * x % mod;
k >>= 1;
}
return res;
}
const int inv2 = 499122177;
const int inv3 = 332748118;
int rev[L4], tw[L4], inv[L4];
inline void operator += (vector<int> &a, vector<int> b)
{
int n = b.size();
a.resize(Max((int)a.size(), n));
for (int i = 0; i < n; ++i)
add(a[i], b[i]);
}
inline void operator -= (vector<int> &a, vector<int> b)
{
int n = b.size();
a.resize(Max((int)a.size(), n));
for (int i = 0; i < n; ++i)
dec(a[i], b[i]);
}
inline void operator *= (vector<int> &a, int k)
{
if (k == -1)
{
int n = a.size();
for (int i = 0; i < n; ++i)
if (a[i])
a[i] = mod - a[i];
}
else
{
int n = a.size();
for (int i = 0; i < n; ++i)
a[i] = 1ll * k * a[i] % mod;
}
}
inline void DFT(vector<int> &a, int opt)
{
int n = a.size(), g = opt == 1 ? 3 : inv3;
for (int i = 0; i < n; ++i)
if (i < rev[i])
std::swap(a[i], a[rev[i]]);
for (int k = 1; k < n; k <<= 1)
{
int w = quick_pow(g, (mod - 1) / (k << 1));
tw[0] = 1;
for (int j = 1; j < k; ++j)
tw[j] = 1ll * tw[j - 1] * w % mod;
for (int i = 0; i < n; i += k << 1)
{
for (int j = 0; j < k; ++j)
{
int u = a[i + j],
v = 1ll * tw[j] * a[i + j + k] % mod;
add(a[i + j] = u, v);
dec(a[i + j + k] = u, v);
}
}
}
if (opt == -1)
{
int inv_n = quick_pow(n, mod - 2);
for (int i = 0; i < n; ++i)
a[i] = 1ll * a[i] * inv_n % mod;
}
}
inline void polyMul(vector<int> &a, vector<int> b)
{
if (!a.size() || !b.size())
{
a.clear();
return ;
}
int m = 0, _n = a.size() + b.size() - 2, n;
for (n = 1; n <= _n; n <<= 1)
++m;
a.resize(n);
b.resize(n);
for (int i = 1; i < n; ++i)
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (m - 1));
DFT(a, 1); DFT(b, 1);
for (int i = 0; i < n; ++i)
a[i] = 1ll * a[i] * b[i] % mod;
DFT(a, -1);
a.resize(_n + 1);
}
int main()
{
read(w);
fac[0] = 1;
for (int i = 1; i <= lim; ++i)
fac[i] = 1ll * i * fac[i - 1] % mod;
ifac[lim] = quick_pow(fac[lim], mod - 2);
for (int i = lim; i >= 1; --i)
ifac[i - 1] = 1ll * ifac[i] * i % mod;
e[0].push_back(1);
for (int i = 0, c; i < w; ++i)
{
read(c);
a.resize(c);
for (int j = 0; j < c; ++j)
a[j] = ifac[j];
for (int j = 0; j <= i; ++j)
{
h[j + 1] = e[j];
polyMul(e[j], a);
e[j] *= -1;
}
for (int j = 0; j <= i + 1; ++j)
e[j] += h[j];
}
read(q);
while (q--)
{
read(n);
int ans = e[0].size() > n ? e[0][n] : 0;
for (int i = 1; i <= w; ++i)
{
int m = Min((int)e[i].size() - 1, n),
res = quick_pow(i, n - m);
for (int j = m; j >= 0; --j)
{
ans = (1ll * e[i][j] * res % mod * ifac[n - j] + ans) % mod;
res = 1ll * res * i % mod;
}
}
put(1ll * fac[n] * ans % mod), putchar('\n');
}
return 0;
}