點分治模板
阿新 • • 發佈:2020-11-19
#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; }