【解题报告】联合省选 2021 A卷
本人被省选搞无语了,水平较低,若被叉请直接私信
考虑二分答案。
设二分的极差为
把
对于一个合法区间,区间内只出现了
时间复杂度
#include<bits/stdc++.h>
using namespace std;
#define FILE
//#define int long long
#define LL long long
#define ull unsigned long long
#define pb push_back
#define pii pair<int, int>
#define fst first
#define scd second
#define randint(l, r) (rand() % ((r) - (l) + 1) + (l))
#define abs(x) ((x) < 0 ? -(x) : (x))
const int MAXN = 2e6 + 10;
const int INF = 2e9;
//const int mod = 998244353;
//const int mod = 1e9 + 7;
int n, m;
int a[MAXN], b[MAXN];
int pre[MAXN], suf[MAXN];
int buk[MAXN];
struct NODE {
int x, opt;
NODE(int _x = 0, int _o = 0) : x(_x), opt(_o) {}
bool operator < (const NODE &b) const {return x < b.x;}
} s[MAXN];
template<typename T> inline void read(T &a) {
a = 0; char c = getchar(); int f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while('0' <= c && c <= '9') {a = (a * 10) + (c ^ 48); c = getchar();}
a *= f;
}
bool chk(int add) {
int p = 1, in = 0;
for(int i = 1; i <= n; ++i) buk[i] = 0;
for(int i = 1, to; i <= (n * 2); ++i) {
while(p <= (n * 2) && s[p].x <= s[i].x + add) {
to = s[p].opt; if(to > n) to -= n;
if(!(buk[to]++)) in++;
p++;
}
if(in == n && pre[i - 1] + suf[p] <= m) return true;
to = s[i].opt; if(to > n) to -= n;
if(!(--buk[to])) in--;
}
return false;
}
signed main() {
#ifdef FILE
freopen("card.in", "r", stdin);
freopen("card.out", "w", stdout);
#endif
read(n); read(m);
for(int i = 1; i <= n; ++i) read(a[i]), s[i] = NODE(a[i], i);
for(int i = 1; i <= n; ++i) read(b[i]), s[i + n] = NODE(b[i], i + n);
sort(s + 1, s + (n * 2) + 1);
for(int i = 1; i <= (n << 1); ++i) pre[i] = pre[i - 1] + (s[i].opt <= n);
for(int i = (n << 1); i >= 1; --i) suf[i] = suf[i + 1] + (s[i].opt <= n);
int L = 0, R = 1e9, mid;
while(L < R) {
mid = (L + R) >> 1;
if(chk(mid)) R = mid;
else L = mid + 1;
}
printf("%d\n", L);
return 0;
}
首先考虑如果没有
考虑如何调整到
不妨设
但是,有时候可能会出现
那么考虑调整一下
对于行的操作:
对于列的操作:
这样之后同一个点的
//Code By CXY07
#include<bits/stdc++.h>
using namespace std;
//#define FILE
#define int long long
#define file(FILENAME) freopen(FILENAME".in", "r", stdin), freopen(FILENAME".out", "w", stdout)
#define randint(l, r) (rand() % ((r) - (l) + 1) + (l))
#define LINE() cout << "LINE = " << __LINE__ << endl
#define debug(x) cout << #x << " = " << x << endl
#define abs(x) ((x) < 0 ? (-(x)) : (x))
#define inv(x) qpow((x), mod - 2)
#define lowbit(x) ((x) & (-(x)))
#define ull unsigned long long
#define pii pair<int, int>
#define LL long long
#define mp make_pair
#define pb push_back
#define scd second
#define vec vector
#define fst first
#define endl '\n'
const int MAXN = 610;
const int MAXM = 5e5 + 10;
const int INF = 2e9;
const double eps = 1e-6;
const double PI = acos(-1);
//const int mod = 1e9 + 7;
//const int mod = 998244353;
//const int G = 3;
//const int base = 131;
int T, n, m;
int a[MAXN][MAXN], b[MAXN][MAXN];
int dis[MAXN], cnt[MAXN], w[MAXN][MAXN];
bool inq[MAXN];
queue<int> Q;
template<typename T> inline bool read(T &a) {
a = 0; char c = getchar(); int f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') {a = a * 10 + (c ^ 48); c = getchar();}
return a *= f, true;
}
template<typename A, typename ...B>
inline bool read(A &x, B &...y) {return read(x) && read(y...);}
void add(int a, int b, int v) {
w[a][b] = v, w[b][a] = (int)1e6 - v;
}
bool BellmanFord() {
memset(cnt, 0, sizeof cnt);
for(int i = 1; i <= n + m; ++i)
dis[i] = 0, inq[i] = true;
for(int t = 1; t <= n + m + 1; ++t) {
bool flag = false;
for(int i = 1, l, r; i <= n + m; ++i) {
if(i <= n) l = n + 1, r = n + m;
else l = 1, r = n;
for(int j = l; j <= r; ++j)
if(dis[j] > dis[i] + w[i][j])
dis[j] = dis[i] + w[i][j], flag = true;
}
if(!flag) break;
if(t == n + m + 1) return false;
}
return true;
}
void solve() {
read(n), read(m); memset(w, 0, sizeof w);
for(int i = 1; i < n; ++i)
for(int j = 1; j < m; ++j)
read(b[i][j]);
for(int i = 1; i <= n; ++i) a[i][1] = 0;
for(int i = 1; i <= m; ++i) a[1][i] = 0;
for(int i = 2; i <= n; ++i)
for(int j = 2; j <= m; ++j)
a[i][j] = b[i - 1][j - 1] - a[i - 1][j] - a[i - 1][j - 1] - a[i][j - 1];
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
if((i + j) & 1) add(j + n, i, a[i][j]);
else add(i, j + n, a[i][j]);
}
}
if(!BellmanFord()) return puts("NO"), void();
puts("YES");
for(int i = 1; i <= n; ++i) {
for(int j = 1, opt; j <= m; ++j) {
opt = ((i + j) & 1) ? -1 : 1;
printf("%lld ", a[i][j] + (dis[i] - dis[j + n]) * opt);
}
putchar('\n');
}
}
signed main () {
#ifdef FILE
freopen(".in", "r", stdin);
freopen(".out", "w", stdout);
#endif
read(T);
while(T--) solve();
return 0;
}
发现若在
- 存在一条从
到 ,且路径上点标号均不小于 的路径。 - 存在一条从
到 ,且路径上点标号均不小于 的路径。
两个东西对称,讨论一个即可。
先讨论第二个条件。可以枚举
第一个条件,只需要把边反过来建即可。最后只需要计算出倒序加入每一条边之后,新增加了多少合法点对,做一个后缀和就行。时间复杂度
//Code By CXY07
#include<bits/stdc++.h>
using namespace std;
//#define FILE
//#define int long long
#define file(FILENAME) freopen(FILENAME".in", "r", stdin), freopen(FILENAME".out", "w", stdout)
#define randint(l, r) (rand() % ((r) - (l) + 1) + (l))
#define LINE() cout << "LINE = " << __LINE__ << endl
#define debug(x) cout << #x << " = " << x << endl
#define abs(x) ((x) < 0 ? (-(x)) : (x))
#define inv(x) qpow((x), mod - 2)
#define min(a, b) (a < b ? a : b)
#define max(a, b) (a > b ? a : b)
#define lowbit(x) ((x) & (-(x)))
#define ull unsigned long long
#define pii pair<int, int>
#define LL long long
#define mp make_pair
#define pb push_back
#define scd second
#define vec vector
#define fst first
#define endl '\n'
const int MAXN = 1e3 + 10;
const int MAXM = 2e5 + 10;
const int INF = 2e9;
const double eps = 1e-6;
const double PI = acos(-1);
//const int mod = 1e9 + 7;
//const int mod = 998244353;
//const int G = 3;
//const int base = 131;
struct EDGE {
int head[MAXN], siz;
int nxt[MAXM], to[MAXM];
inline void add(int x, int y) {
nxt[++siz] = head[x];
to[siz] = y, head[x] = siz;
}
} e[2];
int n, m;
int X[MAXM], Y[MAXM];
int val[2][MAXN][MAXN];
int Ans[MAXM];
template<typename T> inline bool read(T &a) {
a = 0; char c = getchar(); int f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') {a = a * 10 + (c ^ 48); c = getchar();}
return a *= f, true;
}
template<typename A, typename ...B>
inline bool read(A &x, B &...y) {return read(x) && read(y...);}
void DFS(int opt, int x, int st, int v) {
val[opt][st][x] = v;
for(int &i = e[opt].head[x], to; i; i = e[opt].nxt[i]) {
to = e[opt].to[i];
if(to < st || val[opt][st][to] != m + 2) continue;
DFS(opt, to, st, v);
}
}
signed main () {
#ifdef FILE
freopen("graph.in", "r", stdin);
freopen("graph.out", "w", stdout);
#endif
read(n), read(m);
for(int i = 1; i <= m; ++i) read(X[i]), read(Y[i]);
for(int i = 1; i <= n; ++i) {
for(int j = i; j <= n; ++j) val[0][i][j] = val[1][i][j] = m + 2;
val[0][i][i] = val[1][i][i] = m + 1, e[0].siz = e[1].siz = 0;
for(int j = i; j <= n; ++j) e[0].head[j] = e[1].head[j] = 0;
for(int j = m; j >= 1; --j) {
if(X[j] < i || Y[j] < i) continue;
e[0].add(X[j], Y[j]), e[1].add(Y[j], X[j]);
if(val[0][i][X[j]] != m + 2 && val[0][i][Y[j]] == m + 2)
DFS(0, Y[j], i, j);
if(val[1][i][Y[j]] != m + 2 && val[1][i][X[j]] == m + 2)
DFS(1, X[j], i, j);
}
}
for(int i = 1; i <= n; ++i)
for(int j = i; j <= n; ++j)
if(max(val[0][i][j], val[1][i][j]) < m + 2)
Ans[min(val[0][i][j], val[1][i][j])]++;
for(int i = m; i >= 1; --i) Ans[i] += Ans[i + 1];
for(int i = 1; i <= m + 1; ++i) printf("%d ", Ans[i]);
return 0;
}
套路地把路径按
先考虑从
那么现在所有询问都到了
考场脑抽了写了主席树但是懒得重新写了就这样吧
貌似可以用点分治什么的做到一个
#include<bits/stdc++.h>
using namespace std;
//#define FILE
//#define int long long
#define LL long long
#define vec vector
#define pii pair<int, int>
#define fst first
#define scd second
#define pb push_back
#define abs(x) ((x) < 0 ? -(x) : (x))
const int MAXN = 2e5 + 10;
const int MAXM = 5e4 + 10;
const int INF = 2e9;
//const int mod = 998244353;
//const int mod = 1e9 + 7;
struct EDGE {
int head[MAXN], siz;
int nxt[MAXN << 1], to[MAXN << 1];
inline void add(int x, int y) {
nxt[++siz] = head[x];
to[siz] = y; head[x] = siz;
}
} e;
struct Query {
int lca, id;
Query(int _lca = 0, int _id = 0) : lca(_lca), id(_id) {}
};
int n, m, c, q;
int P[MAXM], w[MAXN], fa[MAXN], dep[MAXN];
int dfn[MAXN], dfnc, top[MAXN], p[MAXN][21];
int nxt[MAXN][21], num[MAXM];
int sum[MAXN * 30], ls[MAXN * 30], rs[MAXN * 30], cnt, root[MAXN];
int ss[MAXN], tt[MAXN], Ans[MAXN];
bool vis[MAXN];
vec<Query> qs[MAXN];
template<typename T> inline void read(T &a) {
a = 0; char c = getchar(); int f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while('0' <= c && c <= '9') {a = (a * 10) + (c ^ 48); c = getchar();}
a *= f;
}
void DFS(int x, int f) {
fa[x] = f;
p[x][0] = f, dep[x] = dep[f] + 1;
for(int i = 1; i < 20; ++i)
p[x][i] = p[p[x][i - 1]][i - 1];
for(int i = e.head[x], to; i; i = e.nxt[i]) {
to = e.to[i];
if(to == f) continue;
DFS(to, x);
}
}
int LCA(int x, int y) {
if(dep[x] < dep[y]) swap(x, y);
for(int i = 19; ~i; --i)
if(dep[p[x][i]] >= dep[y]) x = p[x][i];
if(x == y) return x;
for(int i = 19; ~i; --i)
if(p[x][i] ^ p[y][i]) x = p[x][i], y = p[y][i];
return p[x][0];
}
void trans() {
static int id[MAXM];
for(int i = 1; i <= c; ++i) id[P[i]] = i, P[i] = i;
for(int i = 1; i <= n; ++i) w[i] = id[w[i]];
}
void calc1(int x) {
int sav = num[w[x]];
if(w[x]) {
num[w[x]] = x;
nxt[x][0] = num[w[x] + 1];
for(int i = 1; i < 20; ++i)
nxt[x][i] = nxt[nxt[x][i - 1]][i - 1];
}
if(qs[x].size()) {
for(int i = 0; i < qs[x].size(); ++i) {
int s = num[1];
if(dep[s] < dep[qs[x][i].lca]) continue;
for(int j = 19; ~j; --j)
if(dep[nxt[s][j]] >= dep[qs[x][i].lca]) s = nxt[s][j];
Ans[qs[x][i].id] = w[s];
}
qs[x].clear();
}
for(int i = e.head[x], to; i; i = e.nxt[i]) {
to = e.to[i];
if(to == fa[x]) continue;
calc1(to);
}
num[w[x]] = sav;
}
void add(int &x, int pre, int l, int r, int p, int v) {
if(p < l || p > r) return;
x = ++cnt;
sum[x] = sum[pre], ls[x] = ls[pre], rs[x] = rs[pre];
sum[x] += v;
if(l == r) return;
int mid = (l + r) >> 1;
if(p <= mid) add(ls[x], ls[pre], l, mid, p, v);
else add(rs[x], rs[pre], mid + 1, r, p, v);
}
int kth(int a, int b, int l, int r, int k) {
if(sum[a] - sum[b] < k) return -1;
if(l == r) return l;
int mid = (l + r) >> 1, v = sum[ls[a]] - sum[ls[b]];
if(k <= v) return kth(ls[a], ls[b], l, mid, k);
else return kth(rs[a], rs[b], mid + 1, r, k - v);
}
void solve(int ii, int x) {
static int lca, lim, l, r, mid, st, j;
lca = qs[x][ii].lca;
lim = Ans[qs[x][ii].id];
l = 1, r = sum[root[x]] - sum[root[lca]];
if(l > r) return;
while(l < r) {
mid = (l + r + 1) >> 1;
st = num[kth(root[x], root[lca], 1, c, mid)];
for(j = 19; ~j; --j)
if(dep[nxt[st][j]] >= dep[lca]) st = nxt[st][j];
if(w[st] <= lim + 1) l = mid;
else r = mid - 1;
}
st = num[kth(root[x], root[lca], 1, c, l)];
for(j = 19; ~j; --j)
if(dep[nxt[st][j]] >= dep[lca]) st = nxt[st][j];
if(w[st] <= lim + 1)
Ans[qs[x][ii].id] = max(Ans[qs[x][ii].id], kth(root[x], root[lca], 1, c, l));
}
void calc2(int x) {
if(w[x]) add(root[x], root[fa[x]], 1, c, w[x], 1);
else root[x] = root[fa[x]];
int sav = num[w[x]];
if(w[x]) {
num[w[x]] = x;
nxt[x][0] = num[w[x] - 1];
for(int i = 1; i < 20; ++i)
nxt[x][i] = nxt[nxt[x][i - 1]][i - 1];
}
for(int ii = 0, j; ii < qs[x].size(); ++ii) solve(ii, x);
for(int i = e.head[x]; i; i = e.nxt[i])
if(e.to[i] != fa[x]) calc2(e.to[i]);
num[w[x]] = sav;
}
signed main() {
#ifdef FILE
freopen("gem.in", "r", stdin);
freopen("gem.out", "w", stdout);
#endif
read(n), read(m), read(c);
for(int i = 1; i <= c; ++i) read(P[i]);
for(int i = 1; i <= n; ++i) read(w[i]);
trans();
for(int i = 1, x, y; i < n; ++i) {
read(x), read(y);
e.add(x, y), e.add(y, x);
}
DFS(1, 0); read(q);
for(int i = 1; i <= q; ++i) {
read(ss[i]), read(tt[i]);
qs[ss[i]].pb(Query(LCA(ss[i], tt[i]), i));
}
calc1(1);
memset(nxt, 0, sizeof nxt), memset(num, 0, sizeof num);
for(int i = 1; i <= n; ++i) qs[i].clear();
for(int i = 1; i <= q; ++i)
qs[tt[i]].pb(Query(LCA(ss[i], tt[i]), i));
calc2(1);
for(int i = 1; i <= q; ++i) printf("%d\n", Ans[i]);
return 0;
}
被题面送退役了的题......就
考虑
套路地用状压
考虑优化,观察到
那么当前只需要枚举一下前驱状态中,
不知道考场上脑子里是装了什么搞得连题都没看懂,活该退役
//Code By CXY07
#include<bits/stdc++.h>
using namespace std;
//#define FILE
#define int long long
#define file(FILENAME) freopen(FILENAME".in", "r", stdin), freopen(FILENAME".out", "w", stdout)
#define randint(l, r) (rand() % ((r) - (l) + 1) + (l))
#define LINE() cout << "LINE = " << __LINE__ << endl
#define debug(x) cout << #x << " = " << x << endl
#define abs(x) ((x) < 0 ? (-(x)) : (x))
#define inv(x) qpow((x), mod - 2)
#define lowbit(x) ((x) & (-(x)))
#define ull unsigned long long
#define pii pair<int, int>
#define LL long long
#define mp make_pair
#define pb push_back
#define scd second
#define vec vector
#define fst first
#define endl '\n'
const int MAXN = 14;
const int MAXM = 510;
const int INF = 2e9;
const double eps = 1e-6;
const double PI = acos(-1);
//const int mod = 1e9 + 7;
//const int mod = 998244353;
//const int G = 3;
//const int base = 131;
int n, m, Ans, maxp;
int a[MAXN], popc[(1 << (MAXN - 1)) + 10], p2[MAXN];
int dp[(1 << (MAXN - 1)) + 10][MAXN][MAXM];
template<typename T> inline bool read(T &a) {
a = 0; char c = getchar(); int f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') {a = a * 10 + (c ^ 48); c = getchar();}
return a *= f, true;
}
template<typename A, typename ...B>
inline bool read(A &x, B &...y) {return read(x) && read(y...);}
signed main () {
#ifdef FILE
freopen(".in", "r", stdin);
freopen(".out", "w", stdout);
#endif
read(n), read(m); p2[0] = 1;
for(int i = 1; i <= n; ++i) p2[i] = p2[i - 1] << 1;
for(int i = 1; i <= n; ++i) read(a[i]);
maxp = max_element(a + 1, a + n + 1) - a;
for(int i = 1; i < p2[n]; ++i) popc[i] = popc[i >> 1] + (i & 1);
for(int i = 1; i <= n; ++i) {
if(n * (a[maxp] - a[i] + (i > maxp)) > m) continue;
dp[1 << (i - 1)][i][(a[maxp] - a[i] + (i > maxp)) * n] = 1;
}
for(int S = 1; S < p2[n]; ++S) {
for(int y = 1; y <= n; ++y) {
if((S & p2[y - 1]) == 0) continue;
for(int x = 1, nxt; x <= n; ++x) {
if(S & p2[x - 1]) continue;
nxt = S | p2[x - 1];
for(int pre = 0, add; pre <= m; ++pre) {
add = max(a[y] - a[x] + (x > y), 0ll);
if(pre + add * (n - popc[S]) > m) break;
dp[nxt][x][pre + add * (n - popc[S])] += dp[S][y][pre];
}
}
}
}
for(int i = 1; i <= n; ++i)
for(int j = 0; j <= m; ++j)
Ans += dp[p2[n] - 1][i][j];
printf("%lld\n", Ans);
return 0;
}
先考虑建立支配树,那么一个点的受支配集就是支配树上的所有祖先。由于本题范围很小,所以可以考虑
由于一开始
分类讨论 考虑一个询问
若
从
出发,走原图的边且不经过 ,所能达到的所有在支配树上在 子树内的点。
有以下的结论:
若
指向一个点 ,使得 不在 的子树内,那么 的受支配集不改变。
若
那么,只要我不经过
若
若我通过
因此,这条路径的贡献等价于
时间复杂度
//Code By CXY07
#include<bits/stdc++.h>
using namespace std;
//#define FILE
//#define int long long
#define file(FILENAME) freopen(FILENAME".in", "r", stdin), freopen(FILENAME".out", "w", stdout)
#define randint(l, r) (rand() % ((r) - (l) + 1) + (l))
#define LINE() cout << "LINE = " << __LINE__ << endl
#define debug(x) cout << #x << " = " << x << endl
#define abs(x) ((x) < 0 ? (-(x)) : (x))
#define inv(x) qpow((x), mod - 2)
#define lowbit(x) ((x) & (-(x)))
#define ull unsigned long long
#define pii pair<int, int>
#define LL long long
#define mp make_pair
#define pb push_back
#define scd second
#define vec vector
#define fst first
#define endl '\n'
const int MAXN = 3010;
const int INF = 2e9;
const double eps = 1e-6;
const double PI = acos(-1);
//const int mod = 1e9 + 7;
//const int mod = 998244353;
//const int G = 3;
//const int base = 131;
struct EDGE {
int head[MAXN], siz;
int nxt[MAXN << 1], to[MAXN << 1];
inline void add(int x, int y) {
nxt[++siz] = head[x];
to[siz] = y, head[x] = siz;
}
} e, T;
int n, m, q, Ans;
int fa[MAXN], dep[MAXN], dfn[MAXN], siz[MAXN], dfnc;
int dom[MAXN][MAXN];
bool vis[MAXN];
queue<int> Q;
template<typename T> inline bool read(T &a) {
a = 0; char c = getchar(); int f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') {a = a * 10 + (c ^ 48); c = getchar();}
return a *= f, true;
}
template<typename A, typename ...B>
inline bool read(A &x, B &...y) {return read(x) && read(y...);}
void build() {
static int cnt[MAXN];
for(int i = 1; i <= n; ++i)
dom[1][i] = dom[i][i] = true;
for(int ban = 2; ban <= n; ++ban) {
memset(vis, 0, sizeof(bool) * (n + 2));
Q.push(1);
while(Q.size()) {
int x = Q.front(); Q.pop();
if(x == ban || vis[x]) continue;
vis[x] = true;
for(int i = e.head[x], to; i; i = e.nxt[i]) {
to = e.to[i];
if(to == ban || vis[to]) continue;
Q.push(to);
}
}
for(int i = 1; i <= n; ++i)
if(!vis[i]) dom[ban][i] = true;
}
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
if(dom[i][j]) cnt[j]++;
Q.push(1);
while(Q.size()) {
int x = Q.front(); Q.pop();
for(int i = 1; i <= n; ++i) {
if(!dom[x][i]) continue;
if((--cnt[i]) == 1) T.add(x, i), Q.push(i);
}
}
}
void DFS(int x, int f) {
dfn[x] = ++dfnc, fa[x] = f, dep[x] = dep[f] + 1, siz[x] = 1;
for(int i = T.head[x], to; i; i = T.nxt[i]) {
to = T.to[i];
if(to == f) continue;
DFS(to, x); siz[x] += siz[to];
}
}
bool isanc(int x, int y) {
while(y) {
if(x == y) return true;
y = fa[y];
}
return false;
}
int LCA(int x, int y) {
while(x ^ y) {
if(dep[x] < dep[y]) swap(x, y);
x = fa[x];
}
return x;
}
void calc(int x, int ban) {
if(vis[x] || ban == x) return;
vis[x] = true;
if(dfn[ban] <= dfn[x] && dfn[x] <= dfn[ban] + siz[ban] - 1) Ans++;
for(int i = e.head[x], to; i; i = e.nxt[i]) {
to = e.to[i];
calc(to, ban);
}
}
void solve() {
int s, t; read(s), read(t);
if(isanc(t, s)) return puts("0"), void();
if(!isanc(s, t)) s = LCA(s, t);
if(fa[t] == s) return puts("0"), void();
int ban = t; while(fa[ban] ^ s) ban = fa[ban];
memset(vis, 0, sizeof(bool) * (n + 2));
Ans = 0; calc(t, ban);
printf("%d\n", Ans);
}
signed main () {
#ifdef FILE
freopen(".in", "r", stdin);
freopen(".out", "w", stdout);
#endif
read(n), read(m), read(q);
for(int i = 1, x, y; i <= m; ++i) {
read(x), read(y);
e.add(x, y);
}
build(); DFS(1, 0);
while(q--) solve();
return 0;
}
woshishabi
香蕉
我爱上了ywjj
我是giagiagiagiagiagia
我是cxy09
ywjj好漂亮我好爱
ywjj好漂亮我好爱