zoukankan      html  css  js  c++  java
  • Wannafly Camp 2020 Day 2E 阔力梯的树


    搞一波启发式合并即可

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    #define iter set<long long>::iterator
    
    const int N = 100005;
    
    struct myset {
        set <int> s;
        int ans = 0;
        void insert(int x) {
            iter p = s.insert(x).first;
            iter rb = s.end();
            --rb;
            if(p!=s.begin() && p!=rb) {
                iter pre=p, suf=p;
                --pre; ++suf;
                ans += x*x*2;
                ans += (*pre) * (*suf) * 2;
                ans -= x * ((*pre) + (*suf)) * 2;
            }
            if(p!=s.begin() && p==rb) {
                iter pre=p;
                --pre;
                ans += x*x + (*pre)*(*pre) - 2*x*(*pre);
            }
            if(p==s.begin() && p!=rb) {
                iter suf=p;
                ++suf;
                ans += x*x + (*suf)*(*suf) - 2*x*(*suf);
            }
        }
        void merge(myset *ms) {
            for(iter it=ms->s.begin();it!=ms->s.end();it++) {
                insert(*it);
            }
        }
        void print() {
            for(iter it=s.begin();it!=s.end();it++)
                cout<<(*it)<<" ";
        }
    } buf[N];
    
    myset* merge(myset *s1,myset *s2) {
        if(s1->s.size() < s2->s.size()) {
            s2->merge(s1);
            return s2;
        }
        else {
            s1->merge(s2);
            return s1;
        }
    }
    
    int n,p[N],vis[N],ans[N];
    myset *s[N];
    vector <int> g[N];
    
    void print() {
        for(int i=1;i<=n;i++) {
            cout<<"Node "<<i<<": ";
            s[i]->print();
            cout<<endl;
        }
    }
    
    void dfs(int p) {
        vis[p]=1;
        for(int i=0;i<g[p].size();i++) {
            int q=g[p][i];
            if(vis[q]) continue;
            dfs(q);
            s[p]=merge(s[p],s[q]);
        }
        ans[p]=s[p]->ans;
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n;
        for(int i=1;i<=n;i++) {
            s[i]=&buf[i];
            s[i]->insert(i);
        }
        for(int i=2;i<=n;i++) {
            cin>>p[i];
            g[p[i]].push_back(i);
            g[i].push_back(p[i]);
        }
        dfs(1);
        for(int i=1;i<=n;i++) {
            cout<<ans[i]<<endl;
        }
    }
    
  • 相关阅读:
    ArrayList去除集合中自定义对象元素的重复值_对象的成员变量值相同
    去除ArrayList集合中重复字符串元素方式_思路:创建新集合方式
    21班_编程入门测试题
    jh_01_编程入门小案例练习
    排列算法
    HDOJ2030汉字统计
    HDOJ2029Palindromes _easy version
    HDOJ2028Lowest Common Multiple Plus
    HDOJ2027统计元音
    HDOJ2026首字母变大写
  • 原文地址:https://www.cnblogs.com/mollnn/p/12258034.html
Copyright © 2011-2022 走看看