zoukankan      html  css  js  c++  java
  • 4577 [FJOI2018]领导集团问题

    Jisoo

    我们来想一下序列上的\(O(nlog_n)\)是怎么实现的

    每次二分,把当前节点插进去替换,来让答案尽可能的更优。

    换到树上呢?对于以\(u\)作为根节点的子树,我们可以发现去掉\(U\)其实都无所谓了,子树之间没有相互的影响,那就开个集合全扔进去就行了

    然后放进u,并且按照类似于序列情况的方法进行删除操作。

    左后要注意的是如果u是当前序列最小的,就什么都不用做了。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<iomanip>
    #include<cmath>
    #include<stack>
    #include<set>
    #include<vector>
    #include<algorithm>
    using namespace std;
    template<class T>inline void read(T &x)
    {
        x=0;register char c=getchar();register bool f=0;
        while(!isdigit(c))f^=c=='-',c=getchar();
        while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
        if(f)x=-x;
    }
    template<class T>inline void print(T x)
    {
        if(x<0)putchar('-'),x=-x;
        if(x>9)print(x/10);
        putchar('0'+x%10);
    }
    vector<int> v[200005];
    multiset<int> f[200005];
    int n;
    int w[3000005];
    int x,y;
    void merge(int x,int y){
    	if(f[y].size()>f[x].size()){
    		swap(f[y],f[x]);
    	}
    	for(auto ff=f[y].begin();ff!=f[y].end();++ff)
    		f[x].insert(*ff);
    	return ;
    }
    void dfs(int ro){
    	for(auto ff=v[ro].begin();ff!=v[ro].end();++ff){
    		dfs(*ff);
    		merge(ro,*ff);
    	}
    	f[ro].insert(w[ro]);
    	auto ff=f[ro].lower_bound(w[ro]);
    	if(ff!=f[ro].begin()) f[ro].erase(--ff);
    	
    }
    int main(){
    	read(n);
    	for(int i=1;i<=n;++i){
    		read(w[i]);
    	}	
    	for(int i=1;i<n;++i){
    		read(y);
    		v[y].push_back(i+1);
    	}
    	dfs(1);
    	cout<<f[1].size();
    	return 0;
    }
    
  • 相关阅读:
    linux hosts.equiv设置解析
    linux 普通synflood攻击防范网络参数设置
    电脑如何刻录光盘的方式
    Linux系统服务详解
    linux下history命令显示历史指令记录的使用方法
    tkinter模块常用参数
    python使用tkinter做界面之颜色
    python进行linux系统监控
    Windows 系统cmd设置添加静态路由方式
    PyCharm在win10的64位系统安装实例
  • 原文地址:https://www.cnblogs.com/For-Miku/p/15522639.html
Copyright © 2011-2022 走看看