zoukankan      html  css  js  c++  java
  • [十二省联考2019]D2T2春节十二响

    嘟嘟嘟


    这题真没想到这么简单……


    首先有60分大礼:(O(n ^ 2logn))贪心。(我也不知道为啥就是对的)
    然后又送15分链:维护两个堆,每次去堆顶的最大值。


    这时候得到75分已经很开心了,但其实离AC也就差一点点。
    链的做法已经给了我们提示:合并两个堆。其实这就相当于二叉树。那多叉树呢?就合并多个堆呗!从子树向上递归的时候不断将子树启发式合并,复杂度就保证了。


    代码真的很短

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 2e5 + 5;
    inline ll read()
    {
      ll ans = 0;
      char ch = getchar(), last = ' ';
      while(!isdigit(ch)) last = ch, ch = getchar();
      while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
      if(last == '-') ans = -ans;
      return ans;
    }
    inline void write(ll x)
    {
      if(x < 0) x = -x, putchar('-');
      if(x >= 10) write(x / 10);
      putchar(x % 10 + '0');
    }
    
    int n, a[maxn];
    struct Edge
    {
      int nxt, to;
    }e[maxn];
    int head[maxn], ecnt = -1;
    In void addEdge(int x, int y)
    {
      e[++ecnt] = (Edge){head[x], y};
      head[x] = ecnt;
    }
    
    priority_queue<int> q[maxn];
    int siz[maxn], tp[maxn];
    In int dfs(int now)
    {
      int id1 = now;
      for(int i = head[now], v; ~i; i = e[i].nxt)
        {
          v = e[i].to;
          int id2 = dfs(v);
          if(q[id1].size() < q[id2].size()) swap(id1, id2);
          int Siz = q[id2].size();
          for(int j = 1; j <= Siz; ++j) tp[j] = q[id1].top(), q[id1].pop();
          for(int j = 1; j <= Siz; ++j)
    	{
    	  q[id1].push(max(tp[j], q[id2].top()));
    	  q[id2].pop();
    	}
        }
      q[id1].push(a[now]);
      return id1;
    }
    
    int main()
    {
      Mem(head, -1);
      n = read();
      for(int i = 1; i <= n; ++i) a[i] = read();
      for(int i = 2, x; i <= n; ++i) x = read(), addEdge(x, i);
      int id = dfs(1);
      ll ans = 0;
      while(!q[id].empty()) ans += q[id].top(), q[id].pop();
      write(ans), enter;
      return 0;
    }
    

    这题我考场上写了75分,结果成绩一出只剩20分了,当时真的怀疑人生,因为我对自己的暴力有十足的信心。然后查代码的时候看到了触目惊心的一幕: ``` if(judge_line) {work1(); return 0;} ``` 天知道我`judge_line()`后面的括号去哪了。 -Wall没给我报错,自己复查的时候也没发现,编译也能过,就这样白白没了55分。 考场代码全放上来吧 ```c++ #include #include #include #include #include #include #include #include #include #include using namespace std; #define enter puts("") #define space putchar(' ') #define Mem(a, x) memset(a, x, sizeof(a)) #define In inline typedef long long ll; typedef double db; const int INF = 0x3f3f3f3f; const db eps = 1e-8; const int maxn = 2e5 + 5; const int N = 18; In ll read() { ll ans = 0; char ch = getchar(), las = ' '; while(!isdigit(ch)) las = ch, ch = getchar(); while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); if(las == '-') ans = -ans; return ans; } In void write(ll x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar(x % 10 + '0'); } In void MYFILE() { #ifndef mrclr freopen("spring.in", "r", stdin); freopen("spring.out", "w", stdout); #endif }

    int n, a[maxn];
    struct Edge
    {
    int nxt, to;
    }e[maxn];
    int head[maxn], ecnt = -1;
    In void addEdge(int x, int y)
    {
    e[++ecnt] = (Edge){head[x], y};
    head[x] = ecnt;
    }

    int fa[N + 2][maxn], dep[maxn], siz[maxn];
    In void dfs(int now, int _f)
    {
    siz[now] = 1;
    for(int i = 1; (1 << i) <= dep[now]; ++i)
    fa[i][now] = fa[i - 1][fa[i - 1][now]];
    for(int i = head[now], v; ~i; i = e[i].nxt)
    {
    if((v = e[i].to) == _f) continue;
    dep[v] = dep[now] + 1, fa[0][v] = now;
    dfs(v, now);
    siz[now] += siz[v];
    }
    }
    In int lca(int x, int y)
    {
    if(dep[x] < dep[y]) swap(x, y);
    for(int i = N; i >= 0; --i)
    if(dep[x] - (1 << i) >= dep[y]) x = fa[i][x];
    if(x == y) return x;
    for(int i = N; i >= 0; --i)
    if(fa[i][x] ^ fa[i][y]) x = fa[i][x], y = fa[i][y];
    return fa[0][x];
    }

    struct Node
    {
    int val, siz, id;
    In bool operator < (const Node& oth)const
    {
    return val > oth.val || (val == oth.val && siz < oth.siz);
    }
    }t[maxn];
    vector vec[maxn];
    int cnt = 0;
    ll ans = 0;
    In void work0()
    {
    for(int i = 1; i <= n; ++i) t[i] = (Node){a[i], siz[i], i};
    sort(t + 1, t + n + 1);
    for(int i = 1; i <= n; ++i)
    {
    bool flg1 = 0;
    for(int j = 1; j <= cnt && !flg1; ++j)
    {
    bool flg2 = 1;
    for(int k = 0; k < (int)vec[j].size() && flg2; ++k)
    {
    int v = vec[j][k], z = lca(t[i].id, v);
    if(z == v || z == t[i].id) flg2 = 0;
    }
    if(flg2) vec[j].push_back(t[i].id), flg1 = 1;
    }
    if(!flg1) vec[++cnt].push_back(t[i].id), ans += t[i].val;
    }
    write(ans), enter;
    }

    int du[maxn];
    In bool judge_line()
    {
    for(int i = 1; i <= n; ++i) if(du[i] > 2) return 0;
    return 1;
    }
    priority_queue q[3];
    In void dfs1(int now, int _f, int pos)
    {
    q[pos].push(a[now]);
    for(int i = head[now]; ~i; i = e[i].nxt)
    dfs1(e[i].to, now, pos);
    }
    In void work1()
    {
    for(int i = head[1], j = 1; ~i; i = e[i].nxt, ++j)
    dfs1(e[i].to, 1, j);
    while(!q[1].empty() || !q[2].empty())
    {
    if(q[2].empty()) {ans += q[1].top(), q[1].pop(); continue;}
    if(q[1].empty()) {ans += q[2].top(), q[2].pop(); continue;}
    if(q[1].top() >= q[2].top()) ans += q[1].top();
    else ans += q[2].top();
    q[1].pop(), q[2].pop();
    }
    write(ans + a[1]), enter;
    }

    int main()
    {
    MYFILE();
    Mem(head, -1);
    n = read();
    for(int i = 1; i <= n; ++i) a[i] = read();
    for(int i = 2; i <= n; ++i)
    {
    int x = read();
    addEdge(x, i);
    ++du[x], ++du[i];
    }
    if(judge_line) {work1(); return 0;}
    dfs(1, 0);
    if(n <= 2000) {work0(); return 0;}
    work0();
    return 0;
    }
    /*
    8
    1 5 2 3 4 1 4 2
    1 2 1 3 4 5 7
    */

  • 相关阅读:
    SQL Server 2005 中的同义词
    SQL SERVER 2005中同义词实例
    聚集索引和非聚集索引(整理)
    linux kernel中timer的使用
    linux命令: patch
    win7(64位)php5.5-Apache2.4-mysql5.6环境安装
    tasklet和工作队列
    linux串口编程(c)
    Notepad++中Windows,Unix,Mac三种格式
    centos7/redhat7 将网卡名字改成eth样式的方法
  • 原文地址:https://www.cnblogs.com/mrclr/p/10786117.html
Copyright © 2011-2022 走看看