zoukankan      html  css  js  c++  java
  • Ilya And The Tree CodeForces

    ((半个)智商题,主要难度在于实现)

    题意:有一棵n个结点组成的树,其根是编号为1的结点。对于每一个结点,生成从根结点走到这个结点的路径(包括自身),选择路径上的一个点或者不选择任何点,使得其它点的最大公约数最大。每一个结点要分开考虑。

    曾经错误做法:

    ans[x][0]表示走到x点不选择任何点的最大,ans[x][1]表示走到x点选择1个点的最大。

    ans[x][0]=gcd(ans[fa[x]][0],a[x])

    ans[x][1]=max(ans[fa[x]][0],gcd(ans[fa[x]][1],a[x]))

    错的地方:

    如果a>=b,那么gcd(a,c)不一定大于等于gcd(b,c)。这里没有考虑这点。

    举例:有一棵树2-3-4,对于4会得出1,正确是2。

    错误2:set用错,打挂

    事实上,set还有map的遍历都很容易写错,要小心。

    #include<cstdio>
    #include<algorithm>
    #include<set>
    using namespace std;
    struct Edge
    {
        int to,next;
        bool type;
    }edge[420000];
    int n;
    int first[210000],a[210000],num_edge;
    bool vis[210000];
    int fa[210000];
    int ans0[210000];
    set<int> ans1[210000];//记录每个结点可能得到的所有gcd值
    //set<int>::iterator iter;
    int gcd(int a,int b)
    {
        int t;
        while(b!=0)
        {
            t=a;
            a=b;
            b=t%b;
        }
        return a;
    }
    int dfs(int x)
    {
        vis[x]=true;
        int k=first[x];
        ans0[x]=gcd(ans0[fa[x]],a[x]);
        ans1[x].insert(ans0[fa[x]]);
        set<int>::iterator iter=ans1[fa[x]].begin();
        while(iter!=ans1[fa[x]].end())
        {
            ans1[x].insert(gcd(*iter,a[x]));
            iter++;
        }
        while(k!=0)
        {
            if(!vis[edge[k].to])
            {
                fa[edge[k].to]=x;
                dfs(edge[k].to);
            }
            k=edge[k].next;
        }
    }
    int main()
    {
        int i,x,y,k;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            edge[++num_edge].to=y;
            edge[num_edge].next=first[x];
            first[x]=num_edge;
            edge[++num_edge].to=x;
            edge[num_edge].next=first[y];
            first[y]=num_edge;
        }
        ans0[1]=a[1];
        ans1[1].insert(0);
        vis[1]=true;
        k=first[1];
        while(k!=0)
        {
            fa[edge[k].to]=1;
            dfs(edge[k].to);
            k=edge[k].next;
        }
        set<int>::reverse_iterator iter;
        for(i=1;i<=n;i++)
        {
            iter=ans1[i].rbegin();
            printf("%d ",max(*iter,ans0[i]));
        }
        return 0;
    }
  • 相关阅读:
    int.Parse()及其异常判断
    三个框框的EditBox
    等价类的划分方法与EditorBox问题等价类划分
    初学软件测试
    软件测试方法的分类细谈
    浅谈软件测试之回归测试
    白盒测试——基本路径法
    初探灰盒测试——介于白盒测试与黑盒测试的测试
    对闰年测试的非法输入处理的思考
    等价类测试——进一步完善的Web输入合法验证
  • 原文地址:https://www.cnblogs.com/hehe54321/p/cf-842c.html
Copyright © 2011-2022 走看看