为什么Tsub3 前三个呀,感觉复杂度正确呀,还卡了一下上限

P3806 【模板】点分治 1

wwjjue @ 2023-05-08 18:08:30

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
//#define int long long
#define db double
#define fi first
#define se second
#define pb push_back
#define mpa(a,b) make_pair(a,b)
#define forn(i,a,b,c) for(int i = a;i <= b;i += c)
#define forn(i,a,b) for(int i = a;i <= b;i++)
#define _forn(i,a,b) for(int i = a;i >= b;i--)
#define PII pair<int,int>
#define Pii pair<int,int>
#define for_n(i,a,b) for(int i = a;i < b;i++)
//inline int read(){int x=0,f=1; char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x*f;}
//inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); return; }
const int INF = 1e18;
const int N = 1e4 + 10;
const int M = 1e7 + 10;
const int lim = 2e7 + 10;
const int mod = 100003;
const db EPS = 1e-6;
const db PI = 3.1415926;
db n,m,k,q;

pair<int,int> qu[N];

int head[N],tot;
struct Edge
{
    int v,w,next;
}edge[N << 1];

void add(int u,int v,int w)
{
    edge[++tot].v = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot;
}

int mx_dis;

namespace CecDiv
{
    int sz[N],ctr,S;

    int vis[N],judge[M],temp[N],cntt,que[N],cnt;

    void dfs1(int u,int fa)
    {
        int mx = 0; sz[u] = 1;
        for(int i = head[u];i;i = edge[i].next)
        {
            int v = edge[i].v;
            if(vis[v] || v == fa) continue;
            dfs1(v,u);
            if(ctr != -1) return;
            sz[u] += sz[v]; mx = min(mx,sz[v]);
        }

        mx = min(mx,S - sz[u]);
        if(mx <= S / 2)
        {
            ctr = u;
        }
    }

    //处理处所有子树上的边
    void dfs2(int u,int fa,int dis)
    {
        if(dis > M || dis > mx_dis) return;
        temp[++ cntt] = dis;
        for(int i = head[u];i;i = edge[i].next)
        {
            int v = edge[i].v,w = edge[i].w;
            if(v == fa || vis[v]) continue;
            dfs2(v,u,dis + w);
        }
    }

    void run(int u)     //以重心往下
    {
        judge[0] = 1;
        for(int i = head[u];i;i = edge[i].next)
        {
            int v = edge[i].v,w = edge[i].w;
            if(vis[v]) continue;
            dfs2(v,u,w);
            forn(i,1,m)
                forn(j,1,cntt)
                {
                    if(!qu[i].se && temp[j] <= qu[i].fi)
                    {
                        if(judge[qu[i].fi - temp[j]])
                        {
                            qu[i].se = 1;
                        }
                    }
                }
            mx_dis = 0;
            forn(i,1,m)
                if(!qu[i].se)
                    mx_dis = max(mx_dis,qu[i].fi);

            forn(j,1,cntt) judge[temp[j]] = 1,que[++ cnt] = temp[j];
            cntt = 0;
        }

        forn(i,1,cnt) judge[que[i]] = 0; cnt = 0;

        vis[u] = 1;
        for(int i = head[u];i;i = edge[i].next)
        {
            int v = edge[i].v;
            if(vis[v]) continue;
            S = sz[v]; ctr = -1;
            dfs1(v,u);
            run(ctr);     //递归处理
        }
    }

    void Get_pair(int u,int fa = 0)
    {
        S = n; ctr = -1;
        dfs1(u,fa);
        run(ctr);
    }
}

void solve()
{
    cin >> n >> m;

    int u,v,w;
    forn(i,1, n - 1)
    {
        cin >> u >> v >> w;
        add(u,v,w); add(v,u,w);
    }

    //离线处理
    forn(i,1,m)
    {
        cin >> qu[i].fi;
        mx_dis = max(qu[i].fi,mx_dis);
    }

    CecDiv::Get_pair(1);

    forn(i,1,m)
        if(qu[i].se)
            cout << "AYE" << endl;
        else
            cout << "NAY" << endl;
}

signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);

    int t = 1;
//    cin >> t;
    while(t--)
    {
        solve();
    }
}

|