牛客编程巅峰赛S2第3场 - 青铜&白银&黄金 C Tree VI

牛牛打怪

https://ac.nowcoder.com/acm/contest/9246/A

根据题面,可以发现前面层都是完全二叉树,所以可以先预处理出,每一层的节点个数,然后一直往左生儿子,在加上当前节点后如果超过了总结点就返回,先序遍历是一直先往左走,所以需要预处理出当前节点之前的完全二叉树的节点个数,可以根据代码具体理解.

const long long N=1e5+10;
class Solution {
public:
    typedef long long ll;
    ll n=0;
    ll lim=0;
    ll cnt=0;
    ll tot=0;
    ll res=0;
    ll num[N];
    ll head[N];
    ll base[N],pre[N];
    struct Edge{
        int u,v;
    }edge[N<<1];
    void add(ll x, ll y) {
        edge[++tot].u=head[x];
        edge[tot].v=y;
        head[x]=tot;
    }
    void dfs(ll now, ll loc, ll fa, ll dep) {
        if(now!=1) {
            add(now, fa);
            add(fa, now);
        }
        for(ll i=1; i<=lim; ++i) {
            if(pre[dep]>=n || pre[dep]+lim*(loc-1)+i>n) return;
            dfs(++cnt,lim*(loc-1)+i,now,dep+1);
        }
    }
    void dfs_two(ll now, ll fa) {
        if(now!=1) res+=(num[now]^num[fa]);
        for(ll i=head[now]; i; i=edge[i].u) {
            int to=edge[i].v;
            if(to==fa) continue;
            dfs_two(to,now);
        }
    }
    ll tree6(int k, vector<int>& a) {
        n=a.size();
        lim=k*1ll;
        for(int i=0; i<n; ++i) num[i+1]=a[i]*1ll;
        pre[0]=base[0]=1;
        for(int i=1; i<=n; ++i) base[i]=base[i-1]*lim;
        for(int i=1; i<=n; ++i) pre[i]=pre[i-1]+base[i];
        dfs(++cnt,1,0,0);
        dfs_two(1,0);
        return res;
   }
};
全部评论

相关推荐

05-23 20:31
已编辑
武汉大学 Java
内向的柠檬精在研究求职打法:注意把武大标粗标大 本地你俩不是乱杀
点赞 评论 收藏
分享
运营你豪哥:简历改改吧-非本、求职意向技术岗、无实习经历、内容空洞 如果简历不爆改的话,应该是会持续崩溃了 1.把你教育经历放最下面去 2.蓝底照片很奇怪哈,感觉还在高中时代,建议白底重新拍一下 3.校园经历没啥必要,收集和反馈同学们对产品的意见,解决学生和老师之间的沟通,企业招聘不看这些哈 好好思考一下简历的设计和你要表达的重点,再去投简历
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务