点分治模板

题目链接

#include <bits/stdc++.h>
using namespace std;

#define RG register int
#define LL long long

template<typename elemType>
inline void Read(elemType &T){
    elemType X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    T=(w?-X:X);
}

struct Graph{
    struct edge{int Next,to,w;};
    edge G[20010];
    int head[10010];
    int cnt;

    Graph():cnt(2){}
    void clear(int node_num=0){
        cnt=2;
        if(node_num==0) memset(head,0,sizeof(head));
        else fill(head,head+node_num+5,0);
    }
    void add_edge(int u,int v,int w){
        G[cnt].w=w;
        G[cnt].to=v;
        G[cnt].Next=head[u];
        head[u]=cnt++;
    }
};
Graph G;
const int maxn=10010;
vector<pair<int,int> > ask;
vector<int> CurDis;
int Size[maxn],Dis[maxn],ans[maxn];
bool vis[maxn];
int N,M,Root,CurSize,MaxSize;

void GetRoot(int u,int fa){
    Size[u]=1;
    int mx=0;
    for(int i=G.head[u];i;i=G.G[i].Next){
        int v=G.G[i].to;
        if(v==fa || vis[v]) continue;
        GetRoot(v,u);
        Size[u]+=Size[v];
        mx=max(mx,Size[v]);
    }
    mx=max(mx,CurSize-Size[u]);
    if(mx<MaxSize){MaxSize=mx;Root=u;}
}

void GetDis(int u,int fa){
    Size[u]=1;
    CurDis.push_back(Dis[u]);
    for(int i=G.head[u];i;i=G.G[i].Next){
        int v=G.G[i].to;
        if(vis[v] || v==fa) continue;
        Dis[v]=Dis[u]+G.G[i].w;
        GetDis(v,u);
        Size[u]+=Size[v];
    }
}

void Calc(int u,int len,int add){
    CurDis.clear();
    Dis[u]=len;
    GetDis(u,0);
    sort(CurDis.begin(),CurDis.end());
    for(auto it:ask){
        int k=it.first;
        for(int L=0,R=CurDis.size()-1;L<R;++L){
            while(L<R && CurDis[L]+CurDis[R]>k) --R;
            if(CurDis[L]+CurDis[R]==k) ans[it.second]+=add;
        }
    }
    return;
}

void Divide(int u){
    Calc(u,0,1);
    vis[u]=true;
    for(int i=G.head[u];i;i=G.G[i].Next){
        int v=G.G[i].to;
        if(vis[v]) continue;
        Calc(v,G.G[i].w,-1);
        CurSize=MaxSize=Size[v];
        Root=0;GetRoot(v,0);
        Divide(Root);
    }
}

int main(){
    Read(N);Read(M);
    for(int i=1;i<=N-1;++i){
        int u,v,w;
        Read(u);Read(v);Read(w);
        G.add_edge(u,v,w);
        G.add_edge(v,u,w);
    }
    for(int i=1;i<=M;++i){
        int k;Read(k);
        ask.push_back(make_pair(k,i));
    }
    sort(ask.begin(),ask.end());
    CurSize=MaxSize=N;
    Root=0;GetRoot(1,0);Divide(Root);
    for(int i=1;i<=M;++i){
        if(ans[i]) printf("AYE\n");
        else printf("NAY\n");
    }
    return 0;
}
posted @ 2020-11-19 20:15  AE酱  阅读(63)  评论(0编辑  收藏  举报