E. Merging Towers

You have a set of n discs, the i-th disc has radius i. Initially,
these discs are split among m towers: each tower contains at least one
disc, and the discs in each tower are sorted in descending order of
their radii from bottom to top.

You would like to assemble one tower containing all of those discs. To
do so, you may choose two different towers i and j (each containing at
least one disc), take several (possibly all) top discs from the tower
i and put them on top of the tower j in the same order, as long as the
top disc of tower j is bigger than each of the discs you move. You may
perform this operation any number of times.

For example, if you have two towers containing discs [6,4,2,1] and
[8,7,5,3] (in order from bottom to top), there are only two possible
operations:

move disc 1 from the first tower to the second tower, so the towers
are [6,4,2] and [8,7,5,3,1]; move discs [2,1] from the first tower to
the second tower, so the towers are [6,4] and [8,7,5,3,2,1]. Let the
difficulty of some set of towers be the minimum number of operations
required to assemble one tower containing all of the discs. For
example, the difficulty of the set of towers [[3,1],[2]] is 2: you may
move the disc 1 to the second tower, and then move both discs from the
second tower to the first tower.

You are given m−1 queries. Each query is denoted by two numbers ai and
bi, and means “merge the towers ai and bi” (that is, take all discs
from these two towers and assemble a new tower containing all of them
in descending order of their radii from top to bottom). The resulting
tower gets index ai.

For each k∈[0,m−1], calculate the difficulty of the set of towers
after the first k queries are performed.

Input The first line of the input contains two integers n and m
(2≤m≤n≤2⋅105) — the number of discs and the number of towers,
respectively.

The second line contains n integers t1, t2, …, tn (1≤ti≤m), where ti
is the index of the tower disc i belongs to. Each value from 1 to m
appears in this sequence at least once.

Then m−1 lines follow, denoting the queries. Each query is represented
by two integers ai and bi (1≤ai,bi≤m, ai≠bi), meaning that, during the
i-th query, the towers with indices ai and bi are merged (ai and bi
are chosen in such a way that these towers exist before the i-th
query).

Output Print m integers. The k-th integer (0-indexed) should be equal
to the difficulty of the set of towers after the first k queries are
performed.

Example inputCopy 7 4 1 2 3 3 1 4 3 3 1 2 3 2 4 outputCopy 5 4 2 0
Note The towers in the example are:

before the queries: [[5,1],[2],[7,4,3],[6]]; after the first query:
[[2],[7,5,4,3,1],[6]]

这一题,用并查集,相并组的索引值统一用根节点的索引值,这题的每行答案值实际上是序列中除去连续相同的组数值后剩下元素的个数。但是如果原数组直接遍历的话,会超时的。我便超了大半天的时,无奈,参考大佬的代码,才明白答案值可以转化为,长度减1再减去重复组数序列长度减1。这样只要遍历要合并的区间检查其中元素是否与另一个区间是否有连续区间即可。

int main()
{
    cin>>m>>n;
    init(b,m);
    fors(i,n)
    {
        father[i]=i;//并查集初始化
    }
    a.resize(m);
    fors(i,m)
    {
        a[b[i]].push_back(i);//分组
    }
    ll ans=m-1;
    fors(i,m)
    {
        ans-=(i&&b[i]==b[i-1]);//减去重复长度-1
    }
    cout<<ans<<endl;
    fors(i,n-1)
    {
        ll x,y;
        cin>>x>>y;
        ll xx=find_father(x-1),yy=find_father(y-1);//找根节点
        for( ll ts:a[yy])
        {
            if(ts)
                {ans-=(b[ts-1]==xx);}
            if(ts<m-1)
                {ans-=(b[ts+1]==xx);}
        }
        for(int us:a[yy])
        {
            b[us]=xx;//重新安排组
            a[xx].push_back(us);//合并序列
        }
        father[yy]=xx;
        cout<<ans<<endl;
    }
 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值