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; 
}

 

posted @ 2018-07-13 14:44  尹吴潇  阅读(158)  评论(0编辑  收藏  举报