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