[bzoj1316] 树上的询问

  裸的点分治。。

  及时把已经确定的询问清掉就能快不少。时间复杂度O(nlogn*p)

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=10023;
 7 struct zs{int len,id;bool done;}q[103];
 8 struct zs1{int too,pre,dis;}e[maxn<<1];int tot,last[maxn];
 9 int st[maxn],top,pre,sz[maxn],mx[maxn],POI,dis[maxn];
10 bool gg[103],can[1000023],del[maxn];
11 int i,j,k,n,m,rt,mm;
12  
13 int ra;char rx;
14 inline int read(){
15     rx=getchar(),ra=0;
16     while(rx<'0'||rx>'9')rx=getchar();
17     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
18 }
19 inline int max(int a,int b){return a>b?a:b;}
20 void getrt(int x,int fa){
21     sz[x]=1,mx[x]=0;
22     for(int i=last[x];i;i=e[i].pre)if(!del[e[i].too]&&e[i].too!=fa)
23         getrt(e[i].too,x),sz[x]+=sz[e[i].too],mx[x]=max(mx[x],sz[e[i].too]);
24     mx[x]=max(mx[x],POI-sz[x]);
25     if(mx[x]<mx[rt])rt=x;
26 }
27 void getpoi(int x,int fa){
28     st[++top]=dis[x];
29     for(int i=last[x];i;i=e[i].pre)if(!del[e[i].too]&&e[i].too!=fa)
30         dis[e[i].too]=dis[x]+e[i].dis,getpoi(e[i].too,x);
31 }
32 inline void updQ(){
33     mm=m;m=0;
34     for(int i=1;i<=mm;i++)if(!q[i].done)q[++m]=q[i];
35 }
36 void work(int x){
37     int i,j,k;bool flag=0;
38     rt=0,getrt(x,0);
39     can[0]=1;pre=1;
40     for(i=last[rt];i;i=e[i].pre)if(!del[e[i].too]){
41         dis[e[i].too]=e[i].dis,getpoi(e[i].too,rt);
42         for(j=pre;j<=top;j++)
43             for(k=1;k<=m&&q[k].len>=st[j];k++)if(can[q[k].len-st[j]])q[k].done=1,flag=1;
44         while(pre<=top)
45             if(st[pre]<=q[1].len)
46                 can[st[pre++]]=1;
47             else pre++;
48     }
49     if(flag)updQ();
50     if(!m)return;
51     while(top)
52         if(st[top]<=1000000)can[st[top--]]=0;else top--;
53     del[rt]=1;
54     for(i=last[rt];i;i=e[i].pre)if(!del[e[i].too])POI=sz[e[i].too],work(e[i].too);
55 }
56  
57 inline void insert(int a,int b,int c){
58     e[++tot].too=b,e[tot].dis=c,e[tot].pre=last[a],last[a]=tot;
59     e[++tot].too=a,e[tot].dis=c,e[tot].pre=last[b],last[b]=tot;
60 }
61 bool cmp(zs a,zs b){return a.len>b.len;}
62  
63 int main(){mx[0]=1e9;
64     n=read(),m=read();int m1=m;
65     for(i=1;i<n;i++)j=read(),k=read(),insert(j,k,read());
66     for(i=1;i<=m;i++)q[i].len=read(),q[i].id=i;
67     sort(q+1,q+1+m,cmp);
68     while(m&&q[m].len==0)q[m].done=1,m--;
69     POI=n,work(1);
70     for(i=1;i<=m;i++)gg[q[i].id]=1;
71     for(i=1;i<=m1;i++)puts(gg[i]?"No":"Yes");
72     return 0;
73 }
View Code

 

posted @ 2016-06-18 22:36  czllgzmzl  阅读(210)  评论(0编辑  收藏  举报