BZOJ1316: 树上的询问
题解:
点分常数大如狗
正解是离线跑点分
我是一个个跑,理论复杂度一样
慢了10倍+
#include <bits/stdc++.h> using namespace std; #define me(x) memset(x,0,sizeof(x)); #define rint register int #define IL inline #define mid ((h+t)/2) #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) char ss[1<<24],*A=ss,*B=ss; IL char gc() { return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; } template<class T> void read(T &x) { rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48); while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; } const int INF=1e9; const int N=1e5+1e4; int head[N],l,m,n,k,son[N],f[N],d[N],rt,sum; bool ans,vis[N]; struct re{ int a,b,c; }a[N*2]; map<int,int> M; void arr(int x,int y,int z) { a[++l].a=head[x]; a[l].b=y; a[l].c=z; head[x]=l; } void fr(int x,int fa) { f[x]=0; son[x]=1; int u=head[x]; while (u) { int v=a[u].b; if (v!=fa&&vis[v]) { fr(v,x); son[x]+=son[v]; f[x]=max(f[x],son[v]); } u=a[u].a; } f[x]=max(f[x],sum-son[x]); if (f[x]<f[rt]) rt=x; } deque<int> q; void fd(int x,int fa,int z) { int u=head[x]; while (u) { int v=a[u].b; if (x==z) { while (!q.empty()) { M[q.front()]=1; q.pop_front(); } } if (v!=fa&&vis[v]) { d[v]=d[x]+a[u].c; if (M[k-d[v]]) ans=1; q.push_front(d[v]); fd(v,x,z); } u=a[u].a; } } void solve(int x,int y) { //cout<<y<<endl; d[x]=0; vis[x]=0; M.clear(); q.clear(); M[0]=1; fd(x,0,x); int u=head[x]; while (u) { int v=a[u].b; if (vis[v]) { rt=0; sum=son[v]; fr(v,x); solve(rt,y+1); } u=a[u].a; } } int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); read(n); read(m); int x,y,z; M[0]=1; rep(i,1,n-1) { read(x); read(y); read(z); arr(x,y,z); arr(y,x,z); } f[0]=INF; rep(i,1,m) { ans=0; memset(vis,1,sizeof(vis)); read(k); rt=0; fr(1,0); solve(rt,0); if (ans) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }