TLE on #93 求助 悬关
查看原帖
TLE on #93 求助 悬关
498612
Saka_Noa楼主2023/8/18 20:46

卡到了#93TLE
从TLE on #22 , 到#77 ,再到#93 , 尽力了。
求助

#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
const int N = 1e6 + 5;
int in_n, in_l, in_r;
struct edge
{
    int next, to;
    long long w;
} e[N << 1];
int head[N], cnt;
void add(int f, int t, int v)
{
    e[++cnt] = edge{head[f], t, v};
    head[f] = cnt;
}
int ma_t[N], root, si[N], vis[N], dep[N], de[N];
int sum;
long long Check_X;
void pre_dfs(int u, int Fa)
{
    de[u] = de[Fa] + 1;
    dep[u] = 0;
    for (int i = head[u]; i; i = e[i].next)
    {
        int v = e[i].to;
        if (v == Fa || vis[u])
            continue;
        pre_dfs(v, u);
        dep[u] = max(dep[u], dep[v]);
    }
    dep[u]++;
}
void get_core(int u, int Fa)
{
    si[u] = 1;
    ma_t[u] = 0;
    for (int i = head[u]; i; i = e[i].next)
    {
        int v = e[i].to;
        if (v == Fa || vis[v])
            continue;
        get_core(v, u);
        si[u] += si[v];
        ma_t[u] = max(ma_t[u], si[v]);
    }
    ma_t[u] = max(ma_t[u], sum - si[u]);
    if (!root || ma_t[u] < ma_t[root])
        root = u;
}
vector<pair<int, int>> Son;
bool cmp_son(pair<int, int> a, pair<int, int> b)
{
    return dep[a.first] < dep[b.first];
}
int f[N], g[N];
int id_f[N], id_g[N];
void dfs(int u, int Fa, int len)
{
    de[u] = de[Fa] + 1;
    if (g[de[u] - 1] <= len)
    {
        g[de[u] - 1] = len;
        id_g[de[u] - 1] = u;
        // cerr << "cr d: " << de[u] - 1 << "  i: " << u << "  v: " << g[de[u] - 1] << endl;
    }
    for (int i = head[u]; i; i = e[i].next)
    {
        int v = e[i].to;
        if (v == Fa || vis[v])
            continue;
        // //cerr << u << " ---> " << v << endl;
        dfs(v, u, len + (e[i].w >= Check_X ? 1 : -1));
    }
}
struct NODE
{
    int id;
    long long value;
};
deque<NODE> Q;
int ans = -1e6, ans1, ans2;
/*void fut(NODE c)
{
    cerr << "* " << c.id << " " << c.value << " " << id_f[c.id] << endl;
}*/
void calc(int u)
{
    // //cerr << "C\n";
    //cerr << "---------" << u << "----------\n";
    Son.clear();
    // Q.clear();
    for (int i = head[u]; i; i = e[i].next)
    {
        int v = e[i].to;
        if (vis[v])
            continue;
        Son.push_back(make_pair(v, e[i].w));
        // //cerr << u << " " << v << endl;
    }
    if (!Son.size())
        return;
    sort(Son.begin(), Son.end(), cmp_son);
    int mxdep = dep[Son[Son.size() - 1].first], ldep = dep[Son[0].first];
    // //cerr << u << " -" << mxdep << "- " << ldep << endl;
    mxdep = max(mxdep, ldep);
    for (int i = 0; i <= mxdep; i++)
        f[i] = g[i] = -1e9, id_f[i] = id_g[i] = 0;
    f[0] = 0, id_f[0] = u;
    // dfs(Son[0].first, u, (Son[0].second >= Check_X ? 1 : -1));
    // for (int i = 1; i <= ldep; i++)
    //     f[i] = g[i], id_f[i] = id_g[i], g[i] = -1e9, id_g[i] = 0;
    for (pair<int, int> &P : Son)
    {
        // cerr << "     --> " << P.first << " " << dep[P.first] << " <--\n";
        // cerr << "f:";
        // for (int j = 0; j <= mxdep; j++)
        // cerr << f[j] << " " << id_f[j] << endl;
        // cerr << endl;
        dfs(P.first, u, (P.second >= Check_X ? 1 : -1));
        // cerr << "g:";
        // for (int j = 0; j <= mxdep; j++)
        // cerr << g[j] << " "<< id_g[j] << endl;
        // cerr << endl;
        Q.clear();

        ////************

        int rgi = min(ldep, max(in_r - dep[P.first], 1));
        for (int i = 0; i <= rgi; i++)
        {
            while ((!Q.empty()) && f[i] >= Q.back().value)
                Q.pop_back();
            if (f[i] > -1e8)
                Q.push_back(NODE{i, f[i]});
        }

        ////************

        for (int i = dep[P.first]; i >= 1; i--)
        {

            ////************

            // cerr <<" q:\n";
             //for_each(Q.begin(), Q.end(), fut);
            while (rgi <= ldep && rgi + i <= in_r) 
            {
                while ((!Q.empty()) && f[rgi] >= Q.back().value)
                    Q.pop_back();
                if (f[rgi] > -1e8)
                    Q.push_back(NODE{rgi, f[rgi]});
                rgi++;
            }

            while (!Q.empty() && i + Q.front().id < in_l)
                Q.pop_front();
            ////************
            ////cerr << Q.size() << endl;
            if (Q.empty())
                continue;

            int top = Q.front().id;
            long long vl = Q.front().value;
            // for (int j = 1; j <= dep[P.first]; j++)
            //     //cerr << g[j] << " ";
            // cerr << endl;
            //cerr << " top " << top << " " << vl << " " << id_f[top] << " |  " << i << " " << g[i] << " " << id_g[i] << endl;
            if (in_l <= (i + top) && (i + top) <= in_r)
                if (g[i] + vl > ans)
                {
                    ans = g[i] + vl;
                    ans1 = id_g[i];
                    ans2 = id_f[top];
                   //cerr << "D: " << i << " " << id_g[i] << " " << top << " " << id_f[top] << endl;
                    if (ans >= 0)
                        return;
                }
        }
        ldep = dep[P.first];
        for (int i = 1; i <= ldep; i++)
        {
            if (g[i] > f[i])
            {
                f[i] = g[i];
                id_f[i] = id_g[i];
            }
            g[i] = -1e9, id_g[i] = 0;
        }
    }

    // //cerr << endl;
}
void solve(int u)
{
    // //cerr << "S";
    vis[u] = 1;
    calc(u);
    if (ans >= 0)
        return;
    for (int i = head[u]; i; i = e[i].next)
    {
        int v = e[i].to;
        if (vis[v])
            continue;
        root = de[u] = de[v] = 0;
        sum = si[v];
        get_core(v, 0);
        pre_dfs(root, 0);
        solve(root);
    }
}
bool check(long long x)
{
    Check_X = x;
    // //cerr << "E";
    // //cerr << x << endl;
    memset(vis, 0, sizeof vis);
    ans = -1e7, ans1 = ans2 = 0;
    root = de[1] = 0;
    sum = in_n;
    get_core(1, 0);
    // cerr << "root " << root << endl;
    pre_dfs(root, 0);
    solve(root);
    if (ans >= 0)
        return 1;
    else
        return 0;
}
int edg[N] , tot;
int main()
{
    // freopen("data.in", "r", stdin);
    // freopen("150E.out", "w", stdout);
    scanf("%d %d %d", &in_n, &in_l, &in_r);
    // clog << in_n << " " << in_l << " " << in_r << endl;
    long long l = 1e9, r = 0, mid, Ans = 0;
    for (int i = 1; i < in_n; i++)
    {
        // //cerr << "H";
        int u, v;
        long long w;
        scanf("%d%d%lld", &u, &v, &w);
        add(u, v, w);
        add(v, u, w);
        edg[++tot] = w;
    }
    sort(edg + 1,  edg + tot + 1);
    l = 1 , r = tot;
    while (l < r)
    {
        mid = (l + r + 1) >> 1;
   // cerr << "{-----MIIII " << mid << " IIIIM-----}\n";
        if (check(edg[mid]))
        {
           // cerr << "OK-->" << mid << endl;
            l = mid;
        }
        else
            r = mid - 1;
    }
   // cerr << "-->ans:" << l << endl;
    // cout << l << " ";
    check(edg[l]);
    printf("%d %d\n", ans1, ans2);
    // cerr << Ans << " " << ans1 << " " << ans2 << endl;
    return 0;
}
2023/8/18 20:46
加载中...