Broken BST CodeForces

Broken BST CodeForces - 797D

题意:给定一棵任意的树,对树上所有结点的权值运行给定的算法(二叉查找树的查找算法)(treenode指根结点),问对于多少个权值这个算法会返回false。

方法:如果要求对于值x运行算法能访问到结点k,根据给定算法还有树,可以推出对于每个结点k的x的范围(即最小值,最大值)(某结点p左子树的结点的x全部小于p的权值,右子树的结点的x全部大于p的权值)(由于全部权值均为整数,即使只知道小于和大于也可以推出最小值、最大值)。

然而,对于某个结点p的权值q,如果q不能访问到p,但能访问到另一个权值为q的结点,那么也会返回true。也就是对于值q,只要某个权值为q的结点可以由值q访问到,那么答案就要加上权值为q的点的总和。

由于权值的范围有点大,输出的时候不能直接用数组标记权值q能否返回true,必须要用特殊的方法。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 struct X
 5 {
 6     int v;
 7     bool nok;
 8     bool operator<(const X& b) const
 9     {
10         return v<b.v;
11     }
12 }p[100100];
13 int l[100100],r[100100],fa[100100];
14 int min1[100100],max1[100100];
15 int n,root,ans;
16 //bool ok[1000000010];
17 void dfs(int x,int ll)//ll表示左/右子树
18 {
19     /*if(p[fa[x]].nok)
20         p[x].nok=true;
21     else
22     {*/
23         min1[x]=min1[fa[x]];
24         max1[x]=max1[fa[x]];
25         if(ll==0)
26         {
27             max1[x]=min(max1[x],p[fa[x]].v-1);
28             if(min1[x]>p[x].v||max1[x]<p[x].v)
29                 p[x].nok=true;
30         }
31         else
32         {
33             min1[x]=max(min1[x],p[fa[x]].v+1);
34             if(min1[x]>p[x].v||max1[x]<p[x].v)
35                 p[x].nok=true;
36         }
37     //}
38     if(l[x])    dfs(l[x],0);
39     if(r[x])    dfs(r[x],1);
40 }
41 int main()
42 {
43     int i,t;
44     bool boo;
45     scanf("%d",&n);
46     for(i=1;i<=n;i++)
47     {
48         scanf("%d%d%d",&p[i].v,&l[i],&r[i]);
49         fa[l[i]]=fa[r[i]]=i;
50     }
51     for(i=1;i<=n;i++)
52         if(fa[i]==0)
53         {
54             root=i;
55             break;
56         }
57     min1[root]=-0x6f6f6f6f;
58     max1[root]=0x6f6f6f6f;
59     if(l[root])    dfs(l[root],0);
60     if(r[root])    dfs(r[root],1);
61 //    for(i=1;i<=n;i++)
62 //        if(!nok[i])
63 //            ok[v[i]]=true;
64 //    for(i=1;i<=n;i++)
65 //        if(!ok[v[i]])
66 //            ans++;//这样就是"直接用数组标记权值q能否返回true"但空间不够
67     sort(p+1,p+n+1);
68     for(i=0;i<n;)
69     {
70         t=0;
71         boo=false;
72         do
73         {
74             i++;
75             t++;
76             if(!p[i].nok)
77                 boo=true;
78         }
79         while(p[i].v==p[i+1].v);
80         if(boo==false)
81             ans+=t;
82     }
83     printf("%d",ans);
84     return 0;
85 }
原文地址:https://www.cnblogs.com/hehe54321/p/cf-797d.html