lightoj 1128 greatest parents && 跳跳棋

Lightoj 1128 greatest parent

这道题给出一个小根堆,输入v, k,要求求出树根和v节点之间的路径上,权值大于等于k的离树根最近的节点。由于儿子比父亲大,所以就可以用lca的思想,倍增法做这道题,预处理点权即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxn = 1e5 + 5;
 5 int fa[maxn][22], val[maxn], head[maxn], to[maxn], nxt[maxn], n, cnt;
 6 void add(int a, int b)
 7 {
 8     cnt++;
 9     to[cnt] = b;
10     nxt[cnt] = head[a];
11     head[a] = cnt;
12 }
13 void dfs(int x)
14 {
15     for(int i = 1; i <= 20; i++)
16         fa[x][i] = fa[fa[x][i-1]][i-1];
17     for(int i = head[x]; i; i = nxt[i])
18         dfs(to[i]);
19 }
20 int find(int x, int y)
21 {
22     for(int i = 20; i >= 0; i--)
23         if(val[fa[x][i]] >= y)
24             x = fa[x][i];
25     return x;
26 }
27 int main()
28 {
29     int t, q, p, s, k, v;
30     scanf("%d", &t);
31     for(int j = 1; j <= t; j++)
32     {
33         cnt = 0;  //  cnt清零似乎很难想到,在这个地方re了好几次
34         memset(head, 0, sizeof(head));
35         memset(to, 0, sizeof(to));
36         memset(nxt, 0, sizeof(nxt));
37         memset(val, 0, sizeof(val));
38         memset(fa, 0, sizeof(fa));
39         scanf("%d %d", &n, &q);
40         val[0] = 1;
41         for(int i = 1; i < n; i++)
42         {
43             scanf("%d %d", &p, &s);
44             add(p, i);
45             val[i] = s;
46             fa[i][0] = p;
47         }
48         dfs(0);
49         printf("Case %d:\n", j); // 开始少打了这句,wa了,打上之后又wa了,发现少打了冒号……
50         for(int i = 1; i <= q; i++)
51         {
52             scanf("%d %d", &k, &v);
53             printf("%d\n", find(k, v));
54         }
55     }
56     return 0;
57 }

跳跳棋

一道国家集训队的神题,为了方便描述,我们把左边的棋子称为a,中间的棋子称为b,右边的为c。仔细观察跳棋规则,我们会发现当左右两跳棋到中间距离不等时有三种转移方式(因为不能跳过两个棋子)

  1. b往a方向跳
  2. b往c方向跳
  3. a,c离b距离近的往里跳

a,c到b距离相等的时候只有1,2两种转移方式。

转载于:https://www.cnblogs.com/njbw7782/p/10617085.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值