BZOJ2799/POI2012 Salaries

Task
给出一棵n个结点的有根树,结点用正整数1~n编号。
每个结点有一个1~n的正整数权值,不同结点的权值不相同,
并且一个结点的权值一定比它父结点的权值大(根结点的权值最大,一定是n)。现在有些结点的权值是已知的,并且如果一个结点的权值已知,它父结点的权值也一定已知。
问还有哪些结点的权值能够唯一确定。
n<=1,000,000, 1<=pi<=n, 0<=zi<=n.

Solution
根据树的结构,我们可以对每个没有确定大小的点i列出一个不等式:zi<=xi
那么只要按照xi从小到大排序,若考虑点i时只有一个数字可选,那么zi就是唯一的.假如有k个点的xi相同,(当k>1时,它们的zi都无法确定)在备选的所有值中把前k个值删去即可.

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int M=1e6+5;
int mark[M],rt,ec=0,head[M],n,A[M],Bit[M],C[M],dep[M],tot=0,m=0;
struct node{
    int to,nex;
    bool operator<(const node &tmp)const{
        return nex<tmp.nex;
    }
}e[M<<1],B[M];
inline void rd(int &res){
    res=0;char c;
    while(c=getchar(),c<48);
    do res=(res<<1)+(res<<3)+(c^48);
    while(c=getchar(),c>=48);
}
inline void print(int k){
    if(!k)return;
    print(k/10);
    putchar(k%10^48);
}
inline void sc(int k){
    if(k<0){k=-k;putchar('-');}
    print(k);
    if(k==0)putchar('0');
    putchar('\n');
}
void ins(int a,int b){
    e[ec]=(node){a,head[b]};
    head[b]=ec++;
    e[ec]=(node){b,head[a]};
    head[a]=ec++;
}
void dfs(int x,int f,int a,int d){//a 
    dep[x]=d;
    if(A[x])a=A[x];
    else{
        B[++tot]=(node){x,upper_bound(C,C+m,a-1)-C-1};
        a=C[B[tot].nex];
    }
    for(int i=head[x];~i;i=e[i].nex){
        int y=e[i].to;
        if(y==f)continue;
        dfs(y,x,a,d+1);
    }
}
int main(){
    int a,b,i,j,k;
    rd(n);
    memset(head,-1,sizeof(head));
    for(i=1;i<=n;i++){
        rd(a);rd(A[i]);
        if(A[i])mark[A[i]]=1;
        if(i!=a)ins(i,a);
        else rt=i;
    }
    A[rt]=n;
    mark[n]=rt;
    for(i=1;i<=n;i++){
        if(!mark[i])C[m++]=i;//还可选的数字 
    }
    dfs(rt,rt,rt,1);
    sort(B+1,B+1+tot);
    sort(C,C+m);
    k=0;
    for(i=1;i<=tot;i=j){
        j=i;
        while(j<=n&&B[j].nex==B[i].nex)j++;
        if(j-i==1){//B[j].nex就是最后大于的数字 
            if(B[i].nex==k)A[B[i].to]=C[k++];
            else k++;
        }
        else{
            k+=j-i;//
        }
    }
    for(i=1;i<=n;i++)sc(A[i]);
    return 0;
}

展开阅读全文

Python数据分析与挖掘

01-08
92讲视频课+16大项目实战+源码+¥800元课程礼包+讲师社群1V1答疑+社群闭门分享会=99元   为什么学习数据分析?       人工智能、大数据时代有什么技能是可以运用在各种行业的?数据分析就是。       从海量数据中获得别人看不见的信息,创业者可以通过数据分析来优化产品,营销人员可以通过数据分析改进营销策略,产品经理可以通过数据分析洞察用户习惯,金融从业者可以通过数据分析规避投资风险,程序员可以通过数据分析进一步挖掘出数据价值,它和编程一样,本质上也是一个工具,通过数据来对现实事物进行分析和识别的能力。不管你从事什么行业,掌握了数据分析能力,往往在其岗位上更有竞争力。    本课程共包含五大模块: 一、先导篇: 通过分析数据分析师的一天,让学员了解全面了解成为一个数据分析师的所有必修功法,对数据分析师不在迷惑。   二、基础篇: 围绕Python基础语法介绍、数据预处理、数据可视化以及数据分析与挖掘......这些核心技能模块展开,帮助你快速而全面的掌握和了解成为一个数据分析师的所有必修功法。   三、数据采集篇: 通过网络爬虫实战解决数据分析的必经之路:数据从何来的问题,讲解常见的爬虫套路并利用三大实战帮助学员扎实数据采集能力,避免没有数据可分析的尴尬。   四、分析工具篇: 讲解数据分析避不开的科学计算库Numpy、数据分析工具Pandas及常见可视化工具Matplotlib。   五、算法篇: 算法是数据分析的精华,课程精选10大算法,包括分类、聚类、预测3大类型,每个算法都从原理和案例两个角度学习,让你不仅能用起来,了解原理,还能知道为什么这么做。
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值