为什么栈这样写才对?
正确的:
#include<bits/stdc++.h>
#define int long long
#define maxn 40005
#define Q 1e7
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void write(int x){
if(x<0){putchar('-');x=-x;}
if(x>=10)write(x/10);
putchar(x-x/10*10+'0');return;
}
int n,m,siz[maxn],f[maxn],tot,ask[105],ROOT;
bool vis[maxn],ans[10000005],have[10000005];
struct EDGE{int v,w;};
vector<EDGE>edge[maxn];
inline int size(int rt,int fa){
++tot;siz[rt]=1;
for(auto i:edge[rt]){
int v=i.v;if(vis[v]||v==fa)continue;
siz[rt]+=size(v,rt);
}
return siz[rt];
}
inline void dp(int rt,int fa){
f[rt]=tot-siz[rt];
for(auto i:edge[rt]){
int v=i.v;
if(v==fa||vis[v])continue;
f[rt]=max(f[rt],siz[v]);
dp(v,rt);
}
if(f[rt]<f[ROOT])ROOT=rt;
}
int tong[10000005],top;
inline void get(int rt,int fa,int dis){
tong[top++]=dis;
for(auto i:edge[rt]){
int v=i.v,w=i.w;
if(vis[v]||v==fa)continue;
get(v,rt,dis+w);
}
}
inline void calc(int rt){
tot=0;size(rt,rt);
ROOT=rt;dp(rt,rt);
have[0]=true;top=1;tong[0]=0;int res;
for(auto i:edge[ROOT]){
int v=i.v,w=i.w;
if(vis[v])continue;
res=top;get(v,ROOT,w);
for(int j=1;j<=m;++j)for(int k=res;k<top&&(!ans[j]);++k)
if(tong[k]<=ask[j])ans[j]=have[ask[j]-tong[k]];
--res;
while(++res<top)if(tong[res]<=Q)have[tong[res]]=true;
}
while(top--)if(tong[top]<=Q)have[tong[top]]=false;
vis[ROOT]=true;
for(auto i:edge[ROOT]){
if(vis[i.v])continue;
calc(i.v);
}
}
signed main(){
n=read();m=read();
for(int i=1;i<n;++i){
int u=read(),v=read(),w=read();
edge[u].push_back({v,w});
edge[v].push_back({u,w});
}
for(int i=1;i<=m;++i)ask[i]=read();
calc(1);
for(int i=1;i<=m;++i){
if(ans[i])cout<<"AYE\n";
else cout<<"NAY\n";
}
return 0;
}
错误的:
#include<bits/stdc++.h>
#define int long long
#define maxn 10005
#define Q 1e7
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void write(int x){
if(x<0){putchar('-');x=-x;}
if(x>=10)write(x/10);
putchar(x-x/10*10+'0');return;
}
int n,m,siz[maxn],f[maxn],tot,ask[105],ROOT;
bool vis[maxn],ans[10000005],have[10000005];
struct EDGE{int v,w;};
vector<EDGE>edge[maxn];
inline int size(int rt,int fa){
++tot;siz[rt]=1;
for(auto i:edge[rt]){
int v=i.v;if(vis[v]||v==fa)continue;
siz[rt]+=size(v,rt);
}
return siz[rt];
}
inline void dp(int rt,int fa){
f[rt]=tot-siz[rt];
for(auto i:edge[rt]){
int v=i.v;
if(v==fa||vis[v])continue;
f[rt]=max(f[rt],siz[v]);
dp(v,rt);
}
if(f[rt]<f[ROOT])ROOT=rt;
}
int tong[10000005],top;
inline void get(int rt,int fa,int dis){
tong[++top]=dis;
for(auto i:edge[rt]){
int v=i.v,w=i.w;
if(vis[v]||v==fa)continue;
get(v,rt,dis+w);
}
}
inline void calc(int rt){
tot=0;size(rt,rt);
ROOT=rt;dp(rt,rt);
have[0]=true;top=1;tong[1]=0;int res;
for(auto i:edge[ROOT]){
int v=i.v,w=i.w;
if(vis[v])continue;
res=top;get(v,ROOT,w);
for(int j=1;j<=m;++j)for(int k=res+1;k<=top&&(!ans[j]);++k)
if(tong[k]<=ask[j])ans[j]=have[ask[j]-tong[k]];res--;
while(++res<top)if(tong[res]<=Q)have[tong[res]]=true;
}
while(top--)if(tong[top]<=Q)have[tong[top]]=false;
vis[ROOT]=true;
for(auto i:edge[ROOT]){
if(vis[i.v])continue;
calc(i.v);
}
}
signed main(){
n=read();m=read();
for(int i=1;i<n;++i){
int u=read(),v=read(),w=read();
edge[u].push_back({v,w});
edge[v].push_back({u,w});
}
for(int i=1;i<=m;++i)ask[i]=read();
calc(1);
for(int i=1;i<=m;++i){
if(ans[i])cout<<"AYE\n";
else cout<<"NAY\n";
}
return 0;
}