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;
}
posted @ 2020-08-16 22:40  cugbacm03  阅读(237)  评论(0)    收藏  举报