8.8 2020牛客暑期多校训练营(第九场)题解及补题
8.8 2020牛客暑期多校训练营(第九场)题解及补题
比赛过程
A题卡住了思维,后来用Python大法过的,I题用到大数板子的香,F题是最可惜的,写了思路的T了,开始换快读,编译不成功,手欠把sort里面的比较函数删了,赛后才发现。
题解
A Groundhog and 2-Power Representation
题意
给定一个计算式,定义\(2(a)=2^a\)。
计算结果。
解法
python大法好。
也可以用朴素的递归思想,模拟从里到外去括号的过程,加上高精度即可AC
代码
Python:
a = input()
a = a.replace("(", "**(")
print(eval(a))
C++:
#include<bits/stdc++.h>
#define N 20005
#define Ms(a,b) memset(a,b,sizeof a)
#define db(x) cerr<<#x<<"="<<x<<endl;
#define db2(x,y) cerr<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl;
#define db3(x,y,z) cerr<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl;
using namespace std;
char s[N];
struct BIGINT{
int a[185],l;
void clr(){Ms(a,l=0);}
BIGINT operator +(const BIGINT &b)const{
BIGINT c;c.clr();
c.l=max(l,b.l);
for(int i=1;i<=c.l;i++){
c.a[i]+=a[i]+b.a[i];
while(c.a[i]>9)c.a[i]-=10,c.a[i+1]++;
}
if(c.a[c.l+1])c.l++;
return c;
}
BIGINT operator *(const BIGINT &b)const{
BIGINT c;c.clr();
c.l=l+b.l-1;
for(int i=1;i<=l;i++)
for(int j=1;j<=b.l;j++)
c.a[i+j-1]+=a[i]*b.a[j];
for(int i=1;i<=c.l;i++){
c.a[i+1]+=c.a[i]/10,c.a[i]%=10;
if(c.a[c.l+1])c.l++;
}
return c;
}
void operator +=(BIGINT b){*this=*this+b;}
void div2(){
for(int i=l;i>=1;i--){
if(a[i]&1)a[i-1]+=10;
a[i]>>=1;
}
if(l&&!a[l])l--;
}
void Print(){
for(int i=l;i>=1;i--)printf("%d",a[i]);
puts("");
}
}stk[N];
int n,tp;
BIGINT Pow(BIGINT &b){
BIGINT a,res;
a.clr(),res.clr();
a.a[1]=2,a.l=1;
res.a[1]=1,res.l=1;
while(b.l){
if(b.a[1]&1)res=res*a;
b.div2();
if(b.l)a=a*a;
}
return res;
}
int main(){
scanf("%s",s+1),n=strlen(s+1);
for(int i=1;i<=n;i++){
if(s[i]=='2'&&s[i+1]!='(')stk[tp].a[1]+=2;
if(s[i]=='(')++tp,stk[tp].l=1;
if(s[i]==')')stk[tp-1]+=Pow(stk[tp]),tp--;
}
stk[0].Print();
return 0;
}
B Groundhog and Apple Tree
题意
解法
代码
//将内容替换成代码
E Groundhog Chasing Death
题意
给你\(a, b,c, d, x, y\), 求 \(\prod_{i = a}^{b}\prod_{j = c}^{d}gcd(x^i, y^j) \,mod \,998244353\)
解法
假设x和y的一个公共质因子为p,且x质因数分解后有cntx个p,y质因数分解后有cnty个p,那么p的贡献值为
\(p^{min(cntx * i, cnty *j)}\)
当\(cntx * i <= cnty * j\) 即 \(j >= cntx * i / cnty\)时,\(p^{min(cntx * i, cnty *j)} = p ^ {cntx * i}\);
当\(cntx * i > cnty * j\) 即 \(j < cntx * i / cnty\)时,\(p^{min(cntx * i, cnty *j)} = p ^ {cnty * j}\);
那么我们枚举i的时候,对于c <= j <= d,
如果\(cntx * i / cnty >= c\),即有部分j是\(p ^ {cnty * j}\)在做贡献,其中p的幂次和为\(cnty * [c + c + 1 + ... + (min(cntx * i / cnty) - 1)]\)
如果\(cntx * i / cnty < d\),即有部分的j是\(p ^ {cntx* i}\)在做贡献,其中p的幂次和为
\(cntx * i * (d - min(cntx * i / cnty + 1, c) + 1)\)
注意最后再利用快速幂计算所有公共质因数的幂的乘积,存公共质因数的幂的时候利用欧拉降幂
代码
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(0), cin.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e6 + 5;
const int inf = ~0u >> 1;
typedef pair<int, int> P;
#define REP(i, a, n) for (int i = a; i < (n); ++i)
#define PER(i, a, n) for (int i = (n)-1; i >= a; --i)
const ll mod = 998244353;
ll a, b, c, d, x, y;
vector<ll> gcdxy, cntx, cnty, anscnt;
ll qpowmod(ll a, ll b) {
ll ans = 1;
a %= mod;
while (b) {
if (b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
int prime[maxn], tot = 0;
bool vis[maxn] = {true, true};
void screen() {
for (int i = 2; i < maxn; i++) {
if (!vis[i]) prime[tot++] = i;
for (int j = 0; j < tot && (ll)i * prime[j] < maxn; j++) {
vis[i * prime[j]] = true;
if (i % prime[j] == 0) break;
}
}
}
int main() {
screen();
scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &x, &y);
ll g = __gcd(x, y);
for (int i = 0; prime[i] * prime[i] <= g; ++i) {
if (g % prime[i] == 0) {
gcdxy.push_back(prime[i]);
while (g % prime[i] == 0) g /= prime[i];
}
}
if (g > 1) {
gcdxy.push_back(g);
}
int cnt = 0;
ll x1 = x, y1 = y;
for (auto it : gcdxy) {
cnt = 0;
while (x1 % it == 0) {
cnt++;
x1 /= it;
}
cntx.push_back(cnt);
cnt = 0;
while (y1 % it == 0) {
cnt++;
y1 /= it;
}
cnty.push_back(cnt);
}
anscnt.resize(gcdxy.size());
fill(anscnt.begin(), anscnt.end(), 0);
REP(i, a, b + 1) {
REP(j, 0, gcdxy.size()) {
ll sum = 0;
ll t = cntx[j] * i / cnty[j];
if (t >= c) {
ll r = min(t, d);
sum += cnty[j] * (r + c) * (r - c + 1) / 2;
}
if (d > t) {
ll l = max(t + 1, c);
sum += cntx[j] * i * (d - l + 1);
}
anscnt[j] += sum;
anscnt[j] %= (mod - 1);
}
}
ll ans = 1;
REP(i, 0, gcdxy.size()) { ans = ans * qpowmod(gcdxy[i], anscnt[i]) % mod; }
printf("%lld\n", ans);
return 0;
}
F Groundhog Looking Dowdy
题意
给你n天, 每天可以从有一些衣服中选一件,每件衣服都有权值,问你任意选m天,求最大的衣服权值-最小的衣服权值的最小值。
解法
首先将所有衣服按照权值从小到大排序,然后利用尺取法,枚举左端点,控制右端点使得区间中恰好有m件来自不同日期的衣服,答案就是min(ans,downdiness[R]-downdiness[L] )
代码
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(0), cin.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e6 + 5;
const int inf = ~0u >> 1;
typedef pair<int,int> P;
#define REP(i, a, n) for (int i = a; i < (n); ++i)
#define PER(i, a, n) for (int i = (n) - 1; i >= a; --i)
const ll mod = 1e9 + 7;
vector<pair<ll, int> > clo;
int flag[maxn];
int main() {
int n, m;
scanf("%d%d", &n, &m);
REP(i, 1, n + 1) {
int k;
scanf("%d", &k);
while (k--) {
ll x;
scanf("%lld", &x);
clo.push_back(pair<ll, int>{x, i});
}
}
sort(clo.begin(), clo.end());
ll r = 0, ans = inf, cnt = 0;
for (int l = 0; l < clo.size(); ++l) {
while (r < clo.size() && cnt < m) {
if (!flag[clo[r].second]) {
cnt++;
}
flag[clo[r].second]++;
r++;
}
if (cnt == m) {
ans = min(ans, clo[r - 1].first - clo[l].first);
}
flag[clo[l].second]--;
if (!flag[clo[l].second])
cnt--;
}
printf("%lld\n", ans);
return 0;
}
I The Crime-solving Plan of Groundhog
题意
给定n个介于0到9之间的数字,请使用它们生成两个正整数,且不带前导零,乘积最小化。输出乘积
解法
选出最小的个位数挑出来(非零),剩下的组成最小值,相乘
代码
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(0), cin.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 5;
const int inf = ~0u >> 1;
typedef pair<int,int> P;
#define REP(i, a, n) for (int i = a; i < (n); ++i)
#define PER(i, a, n) for (int i = (n) - 1; i >= a; --i)
#define base (int) 1e9
class BigInteger {
private:
vector<int> Integer;
void SetInteger() {
while (this->Integer.size() > 1 && this->Integer.back() == 0) {
this->Integer.pop_back();
}
}
void print() {
SetInteger();
printf("%d", this->Integer.size() == 0 ? 0 : this->Integer.back());
int len = this->Integer.size() - 2;
for (int i = len; i >= 0; i--) {
printf("%09d", this->Integer[i]);
}
}
public:
BigInteger() {}
// 使用string初始化BigInteger,不支持负数
BigInteger(string s) {
if (s.size() == 0) {
Integer.push_back(0);
return;
}
while (s.size() % 9 != 0) {
s = '0' + s;
}
int len = s.size();
for (int i = 0; i < len; i += 9) {
int v = 0;
for (int j = i; j < i + 9; j++) v = v * 10 + (s[j] - '0');
Integer.insert(Integer.begin(), v);
}
}
// 使用char 数组初始化 BigInteger
BigInteger(char c[]) {
string s = c;
new (this) BigInteger(s);
}
//使用 long long 类型初始化 BigInteger
BigInteger(long long x) {
string s = "";
while (x > 0) {
s = char(x % 10 + '0') + s;
x /= 10;
}
new (this) BigInteger(s);
}
// 使用int类型初始化 BigInteger
BigInteger(int x) {
new (this) BigInteger((long long) x);
}
//重载输入运算符
friend istream &operator>>(istream &in, BigInteger &a) {
string s;
cin >> s;
BigInteger temp(s);
a = temp;
return in;
}
//重载输出运算符
friend ostream &operator<<(ostream &out, BigInteger a) {
a.print();
return out;
}
// 重载=运算符
BigInteger &operator=(const BigInteger &a) {
this->Integer = a.Integer;
return *this;
}
//重载<运算符,用于两个大数之间的比较
friend bool operator<(BigInteger a, BigInteger b) {
a.SetInteger();
b.SetInteger();
if (a.Integer.size() != b.Integer.size()) return a.Integer.size() < b.Integer.size();
int len = a.Integer.size() - 1;
for (int i = len; i >= 0; i--) {
if (a.Integer[i] != b.Integer[i]) return a.Integer[i] < b.Integer[i];
}
return false;
}
//重载<运算符,可以用于任意类型的比较
template <typename T> friend bool operator<(BigInteger a, T b) {
BigInteger t((long long) b);
return a < t;
}
//重载>运算符,用于两个大数之间的比较
friend bool operator>(BigInteger a, BigInteger b) {
return b < a;
}
// 重载>运算符,可以用于任意类型的比较
template <typename T> friend bool operator>(BigInteger a, T b) {
BigInteger t((long long) b);
return t < a;
}
//重载==运算符
friend bool operator==(BigInteger a, BigInteger b) {
return !(a < b) && !(b < a);
}
// 重载!=运算符
friend bool operator!=(BigInteger a, BigInteger b) {
return !(a == b);
}
//重载==运算符,可以用于任意类型的比较
template <typename T> friend bool operator==(BigInteger a, T b) {
BigInteger t((long long) b);
return !(a < t) && !(t < a);
}
// 重载<=运算符,可以用于任意类型的比较
template <typename T> friend bool operator<=(BigInteger a, T b) {
return a < b || a == b;
}
// 重载>=运算符,可以用于任意类型的比较
template <typename T> friend bool operator>=(BigInteger a, T b) {
return b < a || b == a;
}
//重载+运算符,用于两个大数相加
BigInteger operator+(BigInteger x) {
BigInteger y = *this, ans;
x.SetInteger();
y.SetInteger();
int carry = 0;
int len = max(x.Integer.size(), y.Integer.size());
for (int i = 0; i < len; i++) {
if (i < (int) x.Integer.size()) carry += x.Integer[i];
if (i < (int) y.Integer.size()) carry += y.Integer[i];
ans.Integer.push_back(carry % base);
carry /= base;
}
if (carry) ans.Integer.push_back(carry);
ans.SetInteger();
return ans;
}
//重载+运算符,用于大数和任意类型相加
template <typename T> BigInteger operator+(T x) {
BigInteger t((long long) x);
return *this + t;
}
//重载后置++运算符
const BigInteger operator++(int) {
BigInteger t = *this;
*this = *this + 1;
return t;
}
//重载前置++运算符
BigInteger &operator++() {
*this = *this + 1;
return *this;
}
//重载+=运算符,用于两个大数相加
BigInteger &operator+=(BigInteger x) {
*this = *this + x;
return *this;
}
//重载+=运算符,用于任意类型相加
template <typename T> BigInteger &operator+=(T x) {
BigInteger t((long long) x);
*this = *this + t;
return *this;
}
//重载-运算符,用于两个大数相减
BigInteger operator-(BigInteger x) {
BigInteger y = *this, ans;
x.SetInteger();
y.SetInteger();
int carry = 0, len = y.Integer.size();
for (int i = 0; i < len; i++) {
carry += y.Integer[i] - (i < (int) x.Integer.size() ? x.Integer[i] : 0);
if (carry < 0) {
ans.Integer.push_back(carry + base);
carry = -1;
} else {
ans.Integer.push_back(carry);
carry = 0;
}
}
ans.SetInteger();
return ans;
}
//重载-运算符,用于大数与任意类型相减
template <typename T> BigInteger operator-(T x) {
BigInteger t((long long) x);
return *this - t;
}
//重载后置--运算符
const BigInteger operator--(int) {
BigInteger t = *this;
*this = *this - 1;
return t;
}
//重载前置--运算符
BigInteger &operator--() {
*this = *this - 1;
return *this;
}
//重载-=运算符,用于两个大数相减
BigInteger &operator-=(BigInteger x) {
*this = *this - x;
return *this;
}
//重载-=运算符,用于大数和任意类型相减
template <typename T> BigInteger &operator-=(T x) {
BigInteger t((long long) x);
*this = *this - t;
return *this;
}
//重载*运算符,用于两个两个大数相乘
BigInteger operator*(BigInteger x) {
BigInteger y = *this, ans;
x.SetInteger();
y.SetInteger();
int xlen = x.Integer.size(), ylen = y.Integer.size();
ans.Integer.assign(xlen + ylen, 0);
for (int i = 0; i < xlen; i++) {
long long carry = 0ll;
for (int j = 0; j < ylen || carry > 0; j++) {
long long s =
ans.Integer[i + j] + carry + (long long) x.Integer[i] * (j < (int) y.Integer.size() ? (long long) y.Integer[j] : 0ll);
ans.Integer[i + j] = s % base;
carry = s / base;
}
}
ans.SetInteger();
return ans;
}
// 重载 *运算符, 用于大数和任意两个数相乘
template <typename T> BigInteger operator*(T x) {
BigInteger t((long long) x);
return *this * t;
}
// 重载*= 算符, 用于两个大数相乘
BigInteger &operator*=(BigInteger x) {
*this = *this * x;
return *this;
}
// 重载*=运算符, 用于大数与任意类型的数相乘
template <typename T> BigInteger &operator*=(T x) {
BigInteger t((long long) x);
*this = *this * t;
return *this;
}
// 重载 / 运算符, 用于两个大数相除
BigInteger operator/(BigInteger x) {
BigInteger y = *this, ans, cur;
x.SetInteger();
y.SetInteger();
int len = y.Integer.size() - 1;
for (int i = len; i >= 0; i--) {
cur.Integer.insert(cur.Integer.begin(), y.Integer[i]);
int t = 0, l = 0, r = base;
while (l <= r) {
int mid = (l + r) >> 1;
if (x * BigInteger(mid) > cur) {
t = mid;
r = mid - 1;
} else
l = mid + 1;
}
cur = cur - BigInteger(t - 1) * x;
ans.Integer.insert(ans.Integer.begin(), t - 1);
}
ans.SetInteger();
return ans;
}
// 重载/运算符, 用于大数和任意类型相除
template <typename T> BigInteger operator/(T x) {
BigInteger y = *this, ans, t((long long) x);
y.SetInteger();
long long cur = 0ll;
int len = y.Integer.size() - 1;
for (int i = len; i >= 0; i--) {
cur = cur * (long long) base + (long long) y.Integer[i];
ans.Integer.insert(ans.Integer.begin(), cur / x);
cur %= x;
}
ans.SetInteger();
return ans;
}
// 重载 /=运算符, 用于大数和大数相除
BigInteger &operator/=(BigInteger x) {
*this = *this / x;
return *this;
}
//重载 /=运算符, 用于大数和任意类型相除
template <typename T> BigInteger &operator/=(T x) {
BigInteger t((long long) x);
*this = *this / t;
return *this;
}
//重载%运算符,用于两个大数之间的取余数操作
BigInteger operator%(BigInteger x) {
BigInteger y = *this, ans;
x.SetInteger();
y.SetInteger();
int len = y.Integer.size() - 1;
for (int i = len; i >= 0; i--) {
ans.Integer.insert(ans.Integer.begin(), y.Integer[i]);
int t = 0, l = 0, r = base;
while (l <= r) {
int mid = (l + r) >> 1;
if (x * BigInteger(mid) > ans) {
t = mid;
r = mid - 1;
} else
l = mid + 1;
}
ans = ans - BigInteger(t - 1) * x;
}
ans.SetInteger();
return ans;
}
// 重载 % 算符, 用于大数和任意类型的数
template <typename T> T operator%(T x) {
BigInteger y = *this;
y.SetInteger();
T ans = (T) 0;
int len = y.Integer.size() - 1;
for (int i = len; i >= 0; i--) {
ans = (ans * (base % x) + y.Integer[i] % x) % x;
}
return ans;
}
// 重载%= 算符, 大数之间
BigInteger &operator%=(BigInteger x) {
*this = *this % x;
return *this;
}
// 重载%=运算符 大数和任意类型
template <typename T> BigInteger &operator%=(T x) {
BigInteger t((long long) x);
*this = *this % t;
return *this;
}
friend BigInteger power(BigInteger a, BigInteger x) {
if (x == BigInteger(0) || a == BigInteger(1)) return BigInteger(1);
BigInteger tmp = power(a, x / 2);
if (x % 2 == 0) return tmp * tmp;
return tmp * tmp * a;
}
// 大数和较小数
template <typename T> friend BigInteger power(BigInteger a, T x) {
return power(a, BigInteger((long long) x));
}
// 大数和大数
friend BigInteger gcd(BigInteger a, BigInteger b) {
a.SetInteger();
b.SetInteger();
while (b > BigInteger(0)) {
BigInteger r = a % b;
a = b;
b = r;
}
a.SetInteger();
return a;
}
// 最小公倍数
friend BigInteger lcm(BigInteger a, BigInteger b) {
return a * b / gcd(a, b);
}
// 大数开方
friend BigInteger sqrt(BigInteger a) {
BigInteger x0 = a, x1 = (a + 1) / 2;
while (x1 < x0) {
x0 = x1;
x1 = (x1 + a / x1) / 2;
}
return x0;
}
// 大数 log
friend int log(BigInteger a, int n) { // log_n(a)
int ans = 0;
a.SetInteger();
while (a > BigInteger(1)) {
ans++;
a /= n;
}
return ans;
}
};
int a[maxn];
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
REP(i, 0, n) {
scanf("%d", &a[i]);
}
sort(a, a + n);
BigInteger x;
int posx = -1, posy = -1;
bool flag = true;
string s;
REP(i, 0, n) {
if (a[i] != 0 && flag) {
flag = false;
x = BigInteger(a[i]);
posx = i;
}
else if (a[i] != 0 && !flag) {
s += a[i] + '0';
posy = i;
break;
}
}
REP(i, 0, n) {
if (i != posx && posy != i) {
s += a[i] + '0';
}
}
//cout << "x = " << x << "y = " << s << endl;
BigInteger ans = x * BigInteger(s);
cout << ans << endl;
}
return 0;
}
J The Escape Plan of Groundhog
题意
解法
代码
//将内容替换成代码
K The Flee Plan of Groundhog
题意
有一个土拨鼠在节点1,一个橘子在节点n,在t时刻之前土拨鼠向着n走,橘子不动,从t时刻开始,橘子开始抓土拨鼠,土拨鼠开始跑,土拨鼠 \(1m/s\) 橘子$ 2m/s$,问还有多长时间橘子才能抓到土拨鼠。
解法
首先要求的 t 时刻土拨鼠的位置,然后土拨鼠需要逃跑,所以得与 n 点背向而跑,这时候有2种可能
- 可供土拨鼠跑的路很长,orange抓到它也没泡到尽头
- 可供土拨鼠跑的路很短,土拨鼠跑到路的尽头等待orange来抓它
所以得求土拨鼠能跑的最远距离, 而且因为背向而跑的,所以他们的相对速度为1m/s,所以orange追上土拨鼠需要花费 (他们 t 时刻相距的距离) 秒。
代码
#pragma region
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
namespace fastIO {
#define BUF_SIZE 100000
#define OUT_SIZE 100000
//fread->R
bool IOerror = 0;
//inline char nc(){char ch=getchar();if(ch==-1)IOerror=1;return ch;}
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if (p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if (pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; }
template <class T>
inline bool R(T &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc())
;
if (IOerror) return false;
if (ch == '-') sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
if (sign) x = -x;
return true;
}
inline bool R(double &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc())
;
if (IOerror) return false;
if (ch == '-') sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';
if (ch == '.') {
double tmp = 1;
ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc())
tmp /= 10.0, x += tmp * (ch - '0');
}
if (sign)
x = -x;
return true;
}
inline bool R(char *s) {
char ch = nc();
for (; blank(ch); ch = nc())
;
if (IOerror)
return false;
for (; !blank(ch) && !IOerror; ch = nc())
*s++ = ch;
*s = 0;
return true;
}
inline bool R(char &c) {
c = nc();
if (IOerror) {
c = -1;
return false;
}
return true;
}
template <class T, class... U>
bool R(T &h, U &... t) { return R(h) && R(t...); }
#undef OUT_SIZE
#undef BUF_SIZE
}; // namespace fastIO
using namespace fastIO;
template <class T>
void _W(const T &x) { cout << x; }
void _W(const int &x) { printf("%d", x); }
void _W(const int64_t &x) { printf("%lld", x); }
void _W(const double &x) { printf("%.16f", x); }
void _W(const char &x) { putchar(x); }
void _W(const char *x) { printf("%s", x); }
template <class T, class U>
void _W(const pair<T, U> &x) { _W(x.F), putchar(' '), _W(x.S); }
template <class T>
void _W(const vector<T> &x) {
for (auto i = x.begin(); i != x.end(); _W(*i++))
if (i != x.cbegin()) putchar(' ');
}
void W() {}
template <class T, class... U>
void W(const T &head, const U &... tail) { _W(head), putchar(sizeof...(tail) ? ' ' : '\n'), W(tail...); }
#pragma endregion
const ll maxn = 1e5 + 500;
const int mod=1e9+7;
ll gcd(ll T, ll b) { return b == 0 ? T : gcd(b, T % b); }
ll lcm(ll T, ll b) { return T / gcd(T, b) * b; }
ll mul(ll a,ll b, ll c) {
ll ans = 0;
while(b) {
if(b&1) {
ans= (ans+a)%c;
b--;
}
b>>=1;
a=(a+a)%c;
}
return ans;
}
ll powmod(ll a,ll b,ll c) {
ll ans = 1;
while(b) {
if(b&1) {
ans = mul(ans,a,c);
b--;
}
b>>=1;
a=mul(a,a,c);
}
return ans ;
}
const int N = 1e5 + 5;
struct node{int to;};
vector <node> G[N];
int d_hog[N], orange[N], f[N];
void dfs(int u, int fa, int d[]) {
f[u] = fa;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i].to;
if (v == fa) continue;
d[v] = d[u] + 1;
dfs(v, u, d);
}
}
void dfs2(int u, int fa, int &maxx) {
maxx = max(maxx, orange[u]);
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i].to;
if (v == fa) continue;
dfs2(v, u, maxx);
}
}
int main() {
int n, t;
memset(d_hog, 0, sizeof(d_hog));
memset(orange, 0, sizeof(orange));
scanf("%d %d", &n, &t);
for (int i = 0; i < n - 1; i++) {
int u, v;
scanf("%d %d", &u, &v);
G[u].push_back({v});
G[v].push_back({u});
}
dfs(n, n, orange); //遍历organge是希望fa保存orange的父节点
int hog_start = 1;
while (t--) { //从1向上寻找t次,找到t秒候hog应该在的位置
hog_start = f[hog_start];
}
int maxx = 0;
dfs2(hog_start, f[hog_start], maxx); //求得hog背离n点而行能走的最大距离(这个距离是以n点位参考点)
int max_dis = maxx - orange[hog_start];
int bw_dis = orange[hog_start]; //t时刻俩者间的距离
if (hog_start == n) //表明土拨鼠和orange已经碰面
printf("0\n");
else if (max_dis >= bw_dis) //表明土拨鼠是在逃跑的路上被捉到的
printf("%d\n", max(1, bw_dis));
else //表明土拨鼠是在最远处等着orange来捉
printf("%d\n", max(1, (max_dis + bw_dis + 1)/ 2));
return 0;
}

浙公网安备 33010602011771号