题目大意

给出一棵n个结点的有根树,结点用正整数1~n编号。

每个结点有一个1~n的正整数权值,不同结点的权值不相同,

并且一个结点的权值一定比它父结点的权值小(根结点的权值最大,一定是n)。

现在有些结点的权值是已知的,并且如果一个结点的权值已知,它父结点的权值也一定已知。

问还有哪些结点的权值能够唯一确定。

最后输出每个点的全值,不知道输出0

n<=1,000,000

分析

我们求出每个点最大可以是什么权值

如果i点权值<=d,而<=d中的权值已经确定了d-1个,那么i的权值也可以确定

按照贪心,我们从小到大填权值

做法

求每个点最大权值就dfs+二分

后面选数就按权值从小到大扫就可以了

solution

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <cctype>
  5. #include <cmath>
  6. #include <algorithm>
  7. using namespace std;
  8. const int M=1000007;
  9. inline int rd(){
  10. int x=0;bool f=1;char c=getchar();
  11. for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
  12. for(;isdigit(c);c=getchar()) x=x*10+c-48;
  13. return f?x:-x;
  14. }
  15. int n,rt;
  16. int g[M],te;
  17. struct edge{int y,next;}e[M];
  18. int vis[M];
  19. int val[M];
  20. int pre[M];
  21. int a[M],tot;
  22. struct node{
  23. int d,id;
  24. node (int dd=0,int ii=0){d=dd;id=ii;}
  25. }b[M];
  26. int num;
  27. bool cmp(node x,node y){return x.d<y.d;}
  28. void addedge(int x,int y){
  29. e[++te].y=y;e[te].next=g[x];g[x]=te;
  30. }
  31. int find(int d){
  32. int l=1,r=tot,mid;
  33. while(l<r){
  34. int mid=(l+r)/2+1;
  35. if(a[mid]>=d) r=mid-1;
  36. else l=mid;
  37. }
  38. return a[l];
  39. }
  40. void dfs(int x,int mx){
  41. if(val[x]) mx=val[x];
  42. else {
  43. mx=find(mx);
  44. b[++num]=node(mx,x);
  45. }
  46. int p,y;
  47. for(p=g[x];p;p=e[p].next)
  48. if((y=e[p].y)!=pre[x]){
  49. dfs(y,mx);
  50. }
  51. }
  52. int main(){
  53. int i,j,x,y,z;
  54. n=rd();
  55. for(i=1;i<=n;i++){
  56. y=rd(),z=rd();
  57. if(i==y) rt=i;
  58. else pre[i]=y,addedge(y,i);
  59. val[i]=z;
  60. vis[z]=1;
  61. }
  62. for(i=1;i<=n;i++)
  63. if(!vis[i]) a[++tot]=i;
  64. dfs(rt,n);
  65. sort(b+1,b+num+1,cmp);
  66. int cnt=0;
  67. j=1;
  68. for(i=1;i<=n;i++){
  69. if(vis[i]){
  70. cnt++;
  71. continue;
  72. }
  73. if(b[j].d==i){
  74. int tp=j;
  75. for(;j<=num&&b[j].d==i;j++);
  76. if(cnt==i-1) val[b[j-1].id]=i;
  77. cnt+=j-tp;
  78. }
  79. }
  80. for(i=1;i<=n;i++) printf("%d\n",val[i]);
  81. return 0;
  82. }

bzoj 2799 [Poi2012]Salaries 性质+二分的更多相关文章

  1. bzoj 2792: [Poi2012]Well【二分+贪心】

    #include<iostream> #include<cstdio> #include<algorithm> using namespace std; const ...

  2. [BZOJ2799][Poi2012]Salaries

    2799: [Poi2012]Salaries Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 91  Solved: 54[Submit][Statu ...

  3. 题解:POI2012 Salaries

    题解:POI2012 Salaries Description The Byteotian Software Corporation (BSC) has \(n\) employees. In BSC ...

  4. 【BZOJ2799】[Poi2012]Salaries 乱搞

    [BZOJ2799][Poi2012]Salaries Description 给出一棵n个结点的有根树,结点用正整数1~n编号.每个结点有一个1~n的正整数权值,不同结点的权值不相同,并且一个结点的 ...

  5. bzoj 2803 [POI2012]prefixuffix hsh+性质

    题目大意 bzoj 2803 对于两个串S1.S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同.例如串ababba和串abbaab是循环相同的. 给出一个长度为n的串S,求满 ...

  6. BZOJ 2792 Poi2012 Well 二分答案

    题目大意:给定一个非负整数序列A.每次操作能够选择一个数然后减掉1,要求进行不超过m次操作使得存在一个Ak=0且max{Ai−Ai+1}最小,输出这个最小值以及此时最小的k 二分答案,然后验证的时候首 ...

  7. bzoj 2792 [Poi2012]Well 二分+dp+two_pointer

    题目大意 给出n个正整数X1,X2,...Xn,可以进行不超过m次操作,每次操作选择一个非零的Xi,并将它减一. 最终要求存在某个k满足Xk=0,并且z=max{|Xi - Xi+1|}最小. 输出最 ...

  8. [BZOJ 1816] [Cqoi2010] 扑克牌 【二分答案】

    题目链接:BZOJ - 1816 题目分析 答案具有可以二分的性质,所以可以二分答案. 验证一个答案 x 是否可行,就累加一下各种牌相对于 x 还缺少的量,如果总和超过了 x 或 m ,就不可行. 因 ...

  9. Bzoj 4371: [IOI2015]sorting排序 二分

    题目 似乎很久没写题解了... 这题是校里胡策的时候的题,比赛因为评测机有点慢+自己代码常数大没快读...被卡t了,但是bzoj上还是A了的...,因为bzoj时限比较宽可以不卡常. 题解: 首先可以 ...

随机推荐

  1. 安装 Win7 的系统的时候如何分区

    解决方案 在安装Win7的系统的时候,可以使用下面方法进行分区: 1. 在出现同意许可条款,勾选“我接受许可条款(A)”后,点击下一步,然后继续下面操作: 2. 进入分区界面,点击“驱动器选项(高级) ...

  2. 01_3_查询指定id的单个对象

    01_3_查询指定id的单个对象 1. 映射文件配置如下信息 <select id="selectStudentById" resultClass="Student ...

  3. 01_9_Struts用ModelDriven接收参数

    01_9_Struts用ModelDriven接收参数 1. 配置struts.xml文件 <package name="user" namespace="/use ...

  4. cocos2dx for lua 简单的翻牌动画

    local x = 20 local y = display.height/2 for i = 1,16 do--创建16张 local cardFg = display.newSprite(&quo ...

  5. NSString 使用 copy、strong

    // 首先定义2个属性 @property (nonatomic, strong) NSString *stStr; @property (nonatomic, copy) NSString *coS ...

  6. CentOS7 安装操作命令

    #timedatectl set-timezone Asia/Shanghai 关闭SELinux vi /etc/sysconfig/selinux #SELINUX=enforcing SELIN ...

  7. Java中将字符串与unicode的相互转换工具类

    unicode编码规则 unicode码对每一个字符用4位16进制数表示.具体规则是:将一个字符(char)的高8位与低8位分别取出,转化为16进制数,如果转化的16进制数的长度不足2位,则在其后补0 ...

  8. crm项目之整体内容(一)

    一.项目背景 YW公司是一家电池供应商,目前由于公司内部的需要,需要做一个CRM项目,需要每一个不同角色的员工登陆系统后处理自己的事情.其流程大致如下: 其项目包括三部分内容: 1.权限分配组件(rb ...

  9. redis的字符串操作以及在django中的使用

    redis ----redis.MongoDB : 非关系型数据库 redis   存储在内存中 MongoDB 存储在硬盘中 l  简介 redis是一个key-value存储系统 , 支持持久化 ...

  10. Java线程和多线程(四)——主线程中的异常

    作为Java的开发者,在运行程序的时候会碰到主线程抛异常的情况.如果开发者使用Java的IDE比如Eclipse或者Intellij IDEA的话,可能是不需要直接面对这个问提的,因为IDE会处理运行 ...