求助#7tle

P3806 【模板】点分治 1

memory_frv @ 2021-06-27 15:37:49

调了好久,最后甚至和题解里的基本一样了,但是题解代码只需要13ms,我需要300ms,求各位帮帮我吧

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
struct edge{
    int u,v,val,nxt;
}e[1000001];
int Minbalance=2147483647,maxp[1000001],rt,head[1000001],cnt=0,sum,vis[1000001],judge[10000001],rem[1000001],query[1000001],avl[1000001],dis[1000001],q[1000001],siz[1000001],n,m,k;
inline void add(int u,int v,int w){
    e[++cnt].v=v,e[cnt].val=w,e[cnt].nxt=head[u],head[u]=cnt;
    e[++cnt].v=u,e[cnt].val=w,e[cnt].nxt=head[v],head[v]=cnt;
}
inline int read(){
    int f=1,x=0;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    return f*x;
}
inline void find_balance(int u,int fa){
    siz[u]=1;
    maxp[u]=0;
    for(int i=head[u];i;i=e[i].nxt){
        int to=e[i].v;
        if(to==fa||vis[to]) continue;
        find_balance(to,u);
        siz[u]+=siz[to];
        maxp[u]=max(maxp[u],siz[to]);
    }
    maxp[u]=max(maxp[u],sum-siz[u]);
    if(maxp[u]<maxp[rt]){
        rt=u;
    }
}
inline void getdis(int now,int fa){
    rem[++rem[0]]=dis[now];
    for(int i=head[now];i;i=e[i].nxt){
        int to=e[i].v;
        if(to==fa||vis[to]) continue;
        dis[to]=dis[now]+e[i].val;
        getdis(to,now);
    }
}
inline void calc(int u){
    int p=0;
    for(int i=head[u];i;i=e[i].nxt){
        int to=e[i].v;
        if(vis[to]) continue;
        rem[0]=0;dis[to]=e[i].val;
        getdis(to,u);
        for(int j=rem[0];j;j--){
            for(int l=1;l<=m;l++){
                if(query[l]>=rem[j])
                avl[l]|=judge[query[l]-rem[j]];
            }
        }
        for(int j=rem[0];j;j--){
            judge[rem[j]]=1;q[++p]=rem[j];
        }
    }
    for(int i=1;i<=p;i++) judge[q[i]]=0;
}
inline void solve(int now){
    vis[now]=judge[0]=1;calc(now);
    for(int i=head[now];i;i=e[i].nxt){
        int to=e[i].v;
        if(vis[to]) continue;
        sum=siz[to];maxp[rt=0]=2147483647;
        find_balance(to,0);solve(rt);
    }
}
int main(){
    n=read(),m=read();int u,v,w;
    for(int i=0;i<n-1;i++){
        u=read(),v=read(),w=read();
        add(u,v,w);
    }
    for(int i=1;i<=m;i++) query[i]=read();
    maxp[rt]=sum=n;
    find_balance(1,0);
    solve(rt);
    for(int i=1;i<=m;i++){
        if(avl[i])  printf("AYE\n");
        else printf("NAY\n");
    }
    return 0;
}

by LawrenceSivan @ 2021-08-08 09:41:16

sum=siz[to];maxp[rt=0]=2147483647;

把后面的 2147483647 改成 size[to] 会快一些


by LawrenceSivan @ 2021-08-08 09:42:09

@memory_frv 我之前就这么写,但是你要是做别的点分治题目就会发现会 T 的很惨


by memory_frv @ 2021-08-08 10:36:30

@LawrenceSivan 谢谢,不过问题好像不在这。。。


by 渔歌 @ 2021-08-12 20:00:04

题目最底下有提示你看看是不是这个问题QAQ


by memory_frv @ 2021-08-13 16:48:04

已解决,玄学错误,我把数组开到十万级别,然后re,通过题面下方的提示判断了dis大于1e7的情况,然后ac。可是我到现在也不知道哪里的问题


|