[十二省联考]春节十二响

一个特殊的启发式合并

大概是sz(a)+sz(b)=sz(max(a,b))

所以其实是一个log

//Love and Freedom.
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
#define ll long long
#define inf 20021225
#define N 200100
using namespace std;

struct edge{int to,lt;}e[N];
int in[N],cnt; int id[N],n; ll st[N],val[N]; priority_queue<ll> q[N];
void add(int x,int y)
{
    e[++cnt].to=y; e[cnt].lt=in[x]; in[x]=cnt;
}
void dfs(int x)
{
    id[x]=x;
    for(int i=in[x];i;i=e[i].lt)
    {
        int y=e[i].to; dfs(y);
        if(i==in[x])
            id[x]=id[y];
        else
        {
            if(q[id[x]].size()<q[id[y]].size())    swap(id[x],id[y]);
            int tot=0;
            while(!q[id[y]].empty())
                st[++tot]=max(q[id[y]].top(),q[id[x]].top()),q[id[y]].pop(),q[id[x]].pop();
            for(int i=1;i<=tot;i++)    q[id[x]].push(st[i]);
        }
    }
    q[id[x]].push(val[x]);
}
int main()
{
    scanf("%d",&n); int fa;
    for(int i=1;i<=n;i++)
        scanf("%lld",&val[i]);
    for(int i=2;i<=n;i++)
        scanf("%d",&fa),add(fa,i);
    dfs(1); ll ans=0;
    while(!q[id[1]].empty())    ans+=q[id[1]].top(),q[id[1]].pop();
    printf("%lld\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/hanyuweining/p/10801734.html

时间: 2024-08-11 19:26:02

[十二省联考]春节十二响的相关文章

「十二省联考 2019」字符串问题

「十二省联考 2019」字符串问题 解题思路 傻逼题.. 考虑问题转化为一个A串向其支配的所有B串的后缀A串连边,如果有环答案 \(-1\) 否则是这个 \(\text{DAG}\) 上最长路径,直接建图是 \(n^2\) 的,考虑优化建图即可. 由于 \(A,B\) 都是原串的一个子串,那么对原串的反串建 SAM,一个子串的后缀就是其所在节点上比它长的串以及,其子树里的所有串. 首先将所有 \(A,B\) 串在 SAM上用倍增定位并新建节点,把SAM上每个节点拆成入点和出点,对于SAM每一个节

「十二省联考 2019」字符串问题 解题报告

「十二省联考 2019」字符串问题 当场就去世了,我这菜人改了一下午 考虑一个A,B之间的连边实际表示了两个A之间的有向边,然后把A的连边处理好,就转成了拓扑排序找环+最长链 但是边数很多,考虑优化连边 A,B之间的连边显然没法优化的,考虑一个B可以表示所有它的后缀A 把串反向建出SAM,然后一个B的后缀就是par树的子树 可以拿倍增定位 好了这题就没了 注意到一个事情,定位的点可能重复,于是对SAM拆点,每个点挂一个vector表示一个A或者B的点在SAM的这个位置 然后考虑如何连边 一个B所

[十二省联考2019]异或粽子(可持久化tire,堆)

[十二省联考2019]异或粽子(luogu) Description 题目描述 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 nn 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 11 到 nn.第 ii 种馅儿具有一个非负整数的属性值 a_iai?.每种馅儿的数量都足够多,即小粽不会因为缺少原料而做不出想要的粽子.小粽准备用这些馅儿来做出 kk 个粽子. 小粽的做法是:选两个整数数 ll, rr,满足 1 \leqslant l \leqslant r

十二省联考

异或粽子: #include<iostream> #include<cstdio> #include<queue> using namespace std; typedef long long i64; const int N=7e5+5; const int D=64; const int S=N*D; int cnt,c[S][2],z[S]; i64 a[N],s[N]; int f[N]; struct inf{ i64 s; int x; bool opera

[十二省联考2019]春节十二响

好后悔考场没思考这道最良心的水题...t1花了我两个半点结果连20都拿不到 哭了 题目描述:略 思路:将一个点下面的几条链合并成一条 用长链剖分的话似乎可以简化操作 实在太水了所以没啥好说的... 1 #include<cstdio> 2 #include<queue> 3 using std::priority_queue; 4 typedef long long lint; 5 const int N=200011; 6 template<typename st>

P5290 [十二省联考2019]春节十二响

题目链接 题意分析 首先考虑链的话 就是将\(1\)部分的两条子链排序之后 贪心合并即可 那么考虑树的话 我们照样合并就行了 首先 排序的话 我们使用堆就可以了 然后 涉及到了两点问题 \(1.\)我们对于\(u\)以及\(v\)这两个维护好的堆合并的话 为了保证时间复杂度 我们需要使用启发式合并 \(2.\)我们由于启发式合并的话涉及到了交换两个堆的问题 听巨佬说 c++11的话 直接swap是\(O(1)\)的 否则的话 直接\(swap\)就是\(O(n)\) 所以我们考虑维护新的编号 然

[十二省联考2019]D2T2春节十二响

嘟嘟嘟 这题真没想到这么简单-- 首先有60分大礼:\(O(n ^ 2logn)\)贪心.(我也不知道为啥就是对的) 然后又送15分链:维护两个堆,每次去堆顶的最大值. 这时候得到75分已经很开心了,但其实离AC也就差一点点. 链的做法已经给了我们提示:合并两个堆.其实这就相当于二叉树.那多叉树呢?就合并多个堆呗!从子树向上递归的时候不断将子树启发式合并,复杂度就保证了. 代码真的很短 #include<cstdio> #include<iostream> #include<

#4349. 「十二省联考 2019」异或粽子

题意内存限制:1024 MiB时间限制:1500 ms小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 $n$ 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 $1$ 到 $n$.第 $i$ 种馅儿具有一个非负整数的属性值 $a_i$.每种馅儿的数量都足够多,即小粽不会因为缺少原料而做不出想要的粽子.小粽准备用这些馅儿来做出 $k$ 个粽子. 小粽的做法是:选两个整数数 $l,r$,满足 $1\le l\le r\le n$,将编号在 $[l,r]$ 范围内

[十二省联考2019]异或粽子 (可持久化01tire 堆)

/* 查询异或最大值的方法是前缀和一下, 在01trie上二分 那么我们可以对于n个位置每个地方先求出最大的数, 然后把n个信息扔到堆里, 当我们拿出某个位置的信息时, 将他去除当前最大后最大的信息插入到堆中 所以动态维护01trie就可以了 */ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #define mm