zoukankan      html  css  js  c++  java
  • [bzoj4919][Lydsy1706月赛]大根堆【dp】【启发式合并】【stl】

    【题目链接】
      https://www.lydsy.com/JudgeOnline/problem.php?id=4919
    【题解】
      很妙的一道题。考虑NlogN的dp求最长上升序列的做法。我们把其中每一个值存入multiset中。那么其中一个值从小到大的排名即为序列末尾为这个值的序列长度。
      现在考虑将其拓展到树上。显然两棵子树互不干扰,所以可以启发式合并。合并完了之后处理根节点,将比它大的第一个数改成它就可以了。如果不存在,直接插入。(想象一条链的过程)。
      时间复杂度:O(NlogN)

    /* --------------
        user Vanisher
        problem tree
    ----------------*/
    # include <bits/stdc++.h>
    # define    ll      long long
    # define    inf     0x3f3f3f3f
    # define    N       200010
    using namespace std;
    int read(){
        int tmp=0, fh=1; char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
        while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
        return tmp*fh;
    } 
    multiset <int> mp[N];
    struct node{
        int val,id,fa;
    }p[N];
    int n,f[N];
    bool cmpval(node a, node b){return a.val<b.val;}
    bool cmpid(node a, node b){return a.id<b.id;}
    int mixed(int x, int y){
        if (mp[x].size()<mp[y].size())
            swap(x,y);
        multiset <int> :: iterator it=mp[y].begin();
        while (it!=mp[y].end()){
            mp[x].insert(*it);
            it++;
        }
        return x; 
    }
    int main(){
        n=read();
        for (int i=1; i<=n; i++){
            p[i].val=read(); p[i].fa=read();
            p[i].id=i;
        }
        sort(p+1,p+n+1,cmpval);
        int las=-1,cnt=0;
        for (int i=1; i<=n; i++){
            if (p[i].val!=las){
                las=p[i].val;
                cnt++;
            } 
            p[i].val=cnt;
        } 
        sort(p+1,p+n+1,cmpid);
        for (int i=1; i<=n; i++) f[i]=i;
        for (int i=n; i>=1; i--){
            multiset <int> :: iterator it=mp[f[i]].lower_bound(p[i].val);
            if (it!=mp[f[i]].end()) mp[f[i]].erase(it);
            mp[f[i]].insert(p[i].val);
            f[p[i].fa]=mixed(f[i],f[p[i].fa]);
        }
        printf("%d
    ",(int)mp[f[1]].size());
        return 0;
    }
    
  • 相关阅读:
    TSP-UK49687
    维度建模的基本原则
    差分约束系统
    随机过程初步
    随机过程——维纳过程
    Xilinx FPGA复位信号设计
    10 Row Abacus
    Python
    FX2LP与FPGA的简单批量回环
    DFT公式的一个简单示例
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9135963.html
Copyright © 2011-2022 走看看