首页 > 其他分享 >Luogu P5465 [PKUSC2018] 星际穿越

Luogu P5465 [PKUSC2018] 星际穿越

时间:2023-01-12 01:33:06浏览次数:52  
标签:一个点 P5465 int Luogu PKUSC2018 long now 第一步 sim

观察可以发现一个结论,可以视作每个点 \(i\) 可以一步到达 \(l_i \sim n\) 的每一个点。

发现对于 \(a< b<x\),\(dist(a, x) \ge dist(b, x)\)

第一步是相当特殊的,因为第一步的起点是一个点,而之后的每一步都可以视作从这一段中的任意点出发

于是我们特殊处理第一步,然后将第二步当作第一步

那么,新的第一步是从 \(l_{x}\sim n\) 的任意一个点出发

第二步是从 \(\min_\limits{k\ge l_x}\{l_k\} \sim n\) 的任意一个点出发

于是可以考虑倍增

\(f_{i, j}\) 表示从 \(j\sim n\) 的任意一个点出发,走 \(2^i\) 步能到达的最靠左的点

那么,走 \(2^i\) 步能到达 \(f_{i,j} \sim n\) 的每一个点

于是我们可以得到转移

\[f_{i, j} = f_{i-1, f_{i-1,j}} \]

初始条件为

\[f_{0,j}=\min_{k\ge j}\{l_k\} \]

那么我们用 \(g_{i,j}\) 表示从 \(j\sim n\) 的任意一个点出发,到 $f_{i,j} \sim j- 1 $ 的最短步数之和

\[g_{i,j} = g_{i-1,j}+2^{i-1}(f_{i-1, j}-f_{i,j}) + g_{i-1,f_{i-1,j}} \]

初始条件为

\[g_{0,j} = j - f_{0,j} \]

计算时倍增即可,注意加上之前被忽略的第一步。

#include <bits/stdc++.h>

using namespace std;
int n, l[300005];
int q, a, b, x;
int f[25][300005];
long long g[25][300005];

long long query(int a, int x) {
    int now = l[x];
    if (now <= a) return x - a;
    long long ans = 0;
    for (int i = log2(n); i >= 0; i--) {
        if (f[i][now] >= a) {
            ans += g[i][now];
            now = f[i][now];
            ans += 1ll * (now - a) * (1ll << i);
        }
    }
    ans += now - a;
    return ans + (x - a);
}

int main() {
    scanf("%d", &n);
    l[1] = 1;
    for (int i = 2; i <= n; i++) {
        scanf("%d", l + i);
    }
    for (int i = n, minx = 0x7fffffff; i >= 1; i--) {
        minx = min(minx, l[i]);
        f[0][i] = minx;
        g[0][i] = i - f[0][i];
    }
    for (int i = 1; i <= log2(n); i++) {
        for (int j = 1; j <= n; j++) {
            f[i][j] = f[i - 1][f[i - 1][j]];
            g[i][j] = g[i - 1][j] + g[i - 1][f[i - 1][j]] + (1ll << (i - 1)) * (f[i - 1][j] - f[i][j]);
        }
    }
    scanf("%d", &q);
    while (q--) {
        scanf("%d%d%d", &a, &b, &x);
        long long ans = query(a, x) - query(b + 1, x), len = b - a + 1;
        long long gcd = __gcd(ans, len);
        printf("%lld/%lld\n", ans / gcd, len / gcd);
    }
    return 0;
}

标签:一个点,P5465,int,Luogu,PKUSC2018,long,now,第一步,sim
From: https://www.cnblogs.com/0922-Blog/p/luogu_P5465.html

相关文章

  • luogu P5291 [十二省联考 2019] 希望
    题面传送门真的很想吐。题目的意思大概就是在一棵树上选出\(k\)个联通块,使得这\(k\)个联通块有交。显然联通块的交还是联通块,因此转化为对联通块计数。而联通块个数等于......
  • [luogu]P2123 皇后游戏
    题目传送门分析和国王游戏一样的思路直接考虑邻项交换观察易知排在后面的大臣获得的奖赏一定更多假设前\(i-1\)位左手上的数和为\(a\),第\(i-1\)位获得奖赏为\(......
  • luogu P1971 [NOI2011] 兔兔与蛋蛋游戏
    题面传送门没想到二分图博弈这么早就考了?首先我们发现,如果将和起点行列之和奇偶性一样的点设为黑色,其余设为白色,那么每次空格只会在异色边之间走,而不会在同色边之间走。......
  • Luogu P4592 [TJOI2018]异或 做题记录
    随机跳的。树上维护序列,显然树剖。维护异或,显然01trie。01trie维护区间异或,显然可持久化一下。看到时限很大,显然可以双log。于是跑一边树剖,再根据id暴力建一个可......
  • luogu P5037 抓捕
    ##题意有$n$个点的图,任意一点$x$到可去另外一点$y$必须互质,即$\gcd(x,y)=1$。图无边权,但是拥有点权。求到终点$en$的最短距离。---##思路此题需使用Dijks......
  • Luogu P4591 [TJOI2018] 碱基序列
    链接难度:\(\texttt{省选/NOI-}\)有\(k\)组,每一组有\(a_i\)个字符串\(t_{k,a_i}\),询问分别在每一组选一个字符串拼成的字符串在文本串\(s\)出现的个数的所有情况......
  • 题解: Luogu P8894 「UOI-R1」求和
    题目链接:link前言我的一个学长在一次比赛中出了这道题,然后,我就把这道题切了其实这道题还是比较简单的,然后我就介绍一下我的比赛时的思路和做法30分做法根据标签我......
  • Luogu P2082 区间覆盖(加强版)
    链接难度:普及/提高-有\(n\)个区间\([s_i,t_i]\),求被这\(n\)个区间覆盖的长度。数据范围:\(n\le10^5,1\les_i<t_i\le10^17\)。把每个区间都换成一组匹配的括......
  • luogu P2757 [国家集训队]等差子序列
    Link题解降智了。。。首先我们不需要关心\(Len\)是多少,只需要找到长度为\(3\)的等差子序列就行了。然后就枚举中点\(mid\),看看存不存在\(l<mid<r\)使得\(a_{mi......
  • 题解 : Luogu P2197 【模板】nim 游戏
    题目链接:link结论如果$a_1\oplusa_2\oplus...\oplusa_n\not=0$,则先手必胜证明操作到最后时,每堆石子数都是\(0\),\(0\oplus0\oplus...\oplus0=0......