zoukankan      html  css  js  c++  java
  • #3052. 「十二省联考 2019」春节十二响 [启发式合并]

    考虑是左边有链右边有链的情况,肯定是取max,次max,次次max(雾
    然后你可以把一棵树当做是若干条链,启发式合并,这题就做完了

    // powered by c++11
    // by Isaunoya
    #include <bits/stdc++.h>
    #define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
    #define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
    using namespace std;
    using db = double;
    using ll = long long;
    using uint = unsigned int;
    #define Tp template
    using pii = pair<int, int>;
    #define fir first
    #define sec second
    Tp<class T> void cmax(T& x, const T& y) {if (x < y) x = y;} Tp<class T> void cmin(T& x, const T& y) {if (x > y) x = y;}
    #define all(v) v.begin(), v.end()
    #define sz(v) ((int)v.size())
    #define pb emplace_back
    Tp<class T> void sort(vector<T>& v) { sort(all(v)); } Tp<class T> void reverse(vector<T>& v) { reverse(all(v)); }
    Tp<class T> void unique(vector<T>& v) { sort(all(v)), v.erase(unique(all(v)), v.end()); }
    const int SZ = 1 << 23 | 233;
    struct FILEIN { char qwq[SZ], *S = qwq, *T = qwq, ch;
    #ifdef __WIN64
    #define GETC getchar
    #else
      char GETC() { return (S == T) && (T = (S = qwq) + fread(qwq, 1, SZ, stdin), S == T) ? EOF : *S++; }
    #endif
      FILEIN& operator>>(char& c) {while (isspace(c = GETC()));return *this;}
      FILEIN& operator>>(string& s) {while (isspace(ch = GETC())); s = ch;while (!isspace(ch = GETC())) s += ch;return *this;}
      Tp<class T> void read(T& x) { bool sign = 0;while ((ch = GETC()) < 48) sign ^= (ch == 45); x = (ch ^ 48);
        while ((ch = GETC()) > 47) x = (x << 1) + (x << 3) + (ch ^ 48); x = sign ? -x : x;
      }FILEIN& operator>>(int& x) { return read(x), *this; } FILEIN& operator>>(ll& x) { return read(x), *this; }
    } in;
    struct FILEOUT {const static int LIMIT = 1 << 22 ;char quq[SZ], ST[233];int sz, O;
      ~FILEOUT() { flush() ; }void flush() {fwrite(quq, 1, O, stdout); fflush(stdout);O = 0;}
      FILEOUT& operator<<(char c) {return quq[O++] = c, *this;}
      FILEOUT& operator<<(string str) {if (O > LIMIT) flush();for (char c : str) quq[O++] = c;return *this;}
      Tp<class T> void write(T x) {if (O > LIMIT) flush();if (x < 0) {quq[O++] = 45;x = -x;}
    		do {ST[++sz] = x % 10 ^ 48;x /= 10;} while (x);while (sz) quq[O++] = ST[sz--];
      }FILEOUT& operator<<(int x) { return write(x), *this; } FILEOUT& operator<<(ll x) { return write(x), *this; }
    } out;
    #define int long long
    int n ;
    const int maxn = 2e5 + 52 ;
    int a[maxn] , fa[maxn] ;
    priority_queue < int > q[maxn] ;
    int top = 0 , st[maxn] ;
    void merge(int x , int y) {
    	while(q[x].size() && q[y].size()) {
    		st[++ top] = max(q[x].top() , q[y].top()) ;
    		q[x].pop() , q[y].pop() ;
    	}
    	if(q[y].size())
    		swap(q[x] , q[y]) ;
    	while(top) q[x].push(st[top --]) ;
    }
    signed main() {
      // code begin.
    	in >> n ;
    	rep(i , 1 , n) 
    		in >> a[i] ;
    	rep(i , 2 , n)
    		in >> fa[i] ;
    	Rep(i , n , 2) {
    		q[i].push(a[i]) ;
    		merge(fa[i] , i) ;
    	}
    	int ans = a[1] ;
    	while(! q[1].empty()) ans += q[1].top() , q[1].pop() ;
    	out << ans << '
    ' ;
    	return 0;
      // code end.
    }
    
  • 相关阅读:
    基于element-ui图片封装组件
    计算时间间隔具体每一天
    C语言学习笔记 —— 函数作为参数
    AtCoder Beginner Contest 049 题解
    AtCoder Beginner Contest 048 题解
    AtCoder Beginner Contest 047 题解
    AtCoder Beginner Contest 046 题解
    AtCoder Beginner Contest 045 题解
    AtCoder Beginner Contest 044 题解
    AtCoder Beginner Contest 043 题解
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12382017.html
Copyright © 2011-2022 走看看