• 目标


    1.树上点分治。

    第一次手写AC点分治呢。bzoj1316

    #include<bits/stdc++.h>
    using namespace std;
    #define N 10010
    set<int> s;
    bool ans [110];
    inline int read(){
        int x=0;char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x;
    }
    int n,m;
    struct E{
        int next,to,cal;
    }e[N<<1];
    int head[N],siz[N],son[N],root,sum,minn,q[110];
    bool vis[N];
    int cnt;
    inline void add(int u,int v,int c){
        e[++cnt].to=v;e[cnt].cal=c;e[cnt].next=head[u];head[u]=cnt;
    }
    void findroot(int u,int fa){
        siz[u]=1,son[u]=0;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(vis[v]||v==fa)continue;
            findroot(v,u);
            siz[u]+=siz[v];
            son[u]=max(son[u],siz[v]);
        }
        int ret=max(sum-siz[u],son[u]);
        if(ret<minn)minn=ret,root=u;
    }
    void getans(int u,int fa,int cal){
        for(int i=1;i<=m;i++){
            if(s.find(q[i]-cal)!=s.end())ans[i]=1;
        }
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(vis[v]||v==fa)continue;
            getans(v,u,cal+e[i].cal);
        }
    }
    void ad(int u,int fa,int cal){
        s.insert(cal);
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(vis[v]||v==fa)continue;
            ad(v,u,cal+e[i].cal);
        }
    }
    void solve(int u){
        vis[u]=1;
        minn=n;s.clear();
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(vis[v])continue;
            getans(v,u,e[i].cal);
            ad(v,u,e[i].cal);
        }
        for(int i=1;i<=m;i++)if(s.find(q[i])!=s.end())ans[i]=1;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(!vis[v]){
                sum=siz[v];root=0;minn=n;
                findroot(v,u);
                solve(root);
            }
        }
    }
    int main(){
        n=read(),m=read();
        int u,v,c;
        for(int i=1;i<n;i++){
            u=read(),v=read(),c=read();
            add(u,v,c);add(v,u,c);
        }
        for(int i=1;i<=m;i++)q[i]=read();
        sum=n,minn=n;
        findroot(1,0);
        solve(root);
        for (int i=1;i<=m;i++) 
        if (ans[i]||q[i]==0) puts("Yes");
        else puts("No");
        return 0;
    }
    View Code

    最近又练了好多点分治的题,得出一个结论。

    我的大代码能力还是有待提高啊。

    (1)我不愿意打太长的代码

    (2)长的代码我很难调试

    这两点导致很多大代码题有时候半途而废,或者挑不出来一直搁置。

    我该怎么样提高我的代码能力呢。。

    2.计算几何

  • 相关阅读:
    terminator shortcut
    支付宝集成错误
    null与DBNULL
    linode接连出问题,我也没看懂英文
    ruby 日期 好函数
    ruby datetime
    act as tree插件
    ruby 时间
    ruby规则引擎
    on ,type等关键词,使用
  • 原文地址:https://www.cnblogs.com/Amphetamine/p/7837182.html
Copyright © 2020-2023  润新知