首页 > 其他分享 >长链剖分入门

长链剖分入门

时间:2022-10-18 14:44:23浏览次数:49  
标签:长链 arr 入门 剖分 int void debug inline cout

模拟赛考到了,但是完全不会。

填个坑。

P5903 【模板】树上 \(k\) 级祖先

#include <bits/stdc++.h>
#define emp emplace_back
using namespace std;
const int N = 5e5 + 5;
using ui = unsigned int;
using LL = long long;

int IO_flg = 0;
int _debug = 1;
class DEBUG {
public:
    inline void IOS() { if(!IO_flg) IO_flg = 1, ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); }
	inline void shift(int x) { _debug = x; }
    inline void read() {}
    inline void write() {}
#define TMP template <typename T>
#define TEMPA template <typename T, typename ...A>
    TMP inline void writeln(T x) { cout << x << endl; }
    TEMPA inline void read(T &x, A&...k) {
		if(!_debug) return;
        cin >> x, read(k...);
    }
    TEMPA inline void write(T x, A ...k) {
		if(!_debug) return;
        cout << x, write(k...);
    }
    TEMPA inline void writeln(T x, A ...k) {
		if(!_debug) return;
        cout << x << ' ', writeln(k...);
    }
    TMP inline void debug(T *arr, int M) {
		if(!_debug) return;
        for(int i = 1; i <= M; ++i) cout << arr[i] << ' ';
        cout << endl;
    }
	TMP inline void debug(vector <T> &arr) {
		if(!_debug) return;
		for(auto x : arr) cout << x << ' ';
		cout << endl;
	}
    TMP inline void debug(set <T> &arr) {
        if(!_debug) return;
        for(auto x : arr) cout << x << ' ';
        cout << endl;
    }
    TMP inline void debug(multiset <T> &arr) {
        for(auto x : arr) cout << x << ' ';
        cout << endl;
    }
    TMP inline void debug(T x) {
		if(!_debug) return;
        cout << "*" << x << endl;
    }
	TEMPA inline void debug(T x, A ...k) {
		if(!_debug) return;
		cout << "*" << x << ' ', debug(k...);
	}
    inline void file(const char *I = "in.txt", const char *O = "Ans.txt") {
        freopen(I, "r", stdin), freopen(O, "w", stdout);
    }
    inline void Exit() {
        if(!_debug) return;
        exit(0);
    }
    inline void judge(bool Exp) {
        if(!_debug) return;
        if(!Exp) 
            puts("Expression False!"), exit(0);
        puts("Expression True.");
    }
}D;

int n, q, S, rt;
int g[N], d[N], f[N][23], son[N], dep[N], top[N], ans;
// g[i] = log2(i), d[x] = depth of node x, dep[x] = length of chains
// son[x], top[x]
vector <int> Link[N], up[N], dw[N];
// up, dw: the node you get with skipping on the Long chain up and down
LL Ans;

inline ui gen(ui x) {
    return x ^= x << 13, x ^= x >> 17, x ^= x << 5, S = x;
}

void dfs(int x) {
    dep[x] = d[x] = d[f[x][0]] + 1;
    for(auto y : Link[x]) {
        f[y][0] = x;
        for(int i(0); f[y][i]; ++i) f[y][i + 1] = f[f[y][i]][i]; // f[i][j] = fa^(2^j)[i]
       dfs(y);
        if(dep[y] > dep[x]) dep[x] = dep[y], son[x] = y;
    }
}

void dfs(int x, int p) { // p = top of the chain
    top[x] = p;
    if(x == p) {
        for(int i = 0, now = x; i <= dep[x] - d[x]; ++i) 
            up[x].emp(now), now = f[now][0]; // go up
        for(int i = 0, now = x; i <= dep[x] - d[x]; ++i) 
            dw[x].emp(now), now = son[now]; // go down
    }
    if(son[x]) dfs(son[x], p);
    for(auto y : Link[x]) if(y != son[x]) dfs(y, y);
}

inline int ask(int x, int k) {
    if(!k) return x;
    x = f[x][g[k]], k -= 1 << g[k], k -= d[x] - d[top[x]], x = top[x];
	// first skip 2^g[k] steps, then skip to the top of the current chain
    return k >= 0 ? up[x][k] : dw[x][-k];
}

signed main() {
    D.file("in.txt", "Ans.txt");
    scanf("%d %d %d", &n, &q, &S), g[0] = -1;
    for(int i = 1; i <= n; ++i) 
        scanf("%d", &f[i][0]), Link[f[i][0]].emp(i), g[i] = g[i >> 1] + 1;
    rt = Link[0][0], dfs(rt), dfs(rt, rt);
    for(int i = 1, x, k; i <= q; ++i) {
        x = (gen(S) ^ ans) % n + 1, k = (gen(S) ^ ans) % d[x];
        Ans xor_eq 1LL * i * (ans = ask(x, k));
    }
    printf("%lld", Ans);
    return 0;
}

标签:长链,arr,入门,剖分,int,void,debug,inline,cout
From: https://www.cnblogs.com/Doge297778/p/16802499.html

相关文章

  • 【2022.10.18】Linux入门基础(1)
    内容概要主题:linux运维(记)linux基础几乎以记忆为主(理论知识)运维的本质服务器介绍服务器品牌服务器参数服务器组件磁盘阵列虚拟化技术虚拟化软件安装虚......
  • HM-SCAli4【服务治理介绍、nacos入门】
    1服务治理介绍先来思考一个问题通过上一章的操作,我们已经可以实现微服务之间的调用。但是我们把服务提供者的网络地址(ip,端口)等硬编码到了代码中,这种做法存在许多问题:......
  • 一篇文章带你了解网页框架——Vue简单入门
    一篇文章带你了解网页框架——Vue简单入门这篇文章将会介绍我们前端入门级别的框架——Vue的简单使用如果你以后想从事后端程序员,又想要稍微了解前端框架知识,那么这篇文......
  • Golang入门:Linux上的go语言安装与配置
    Tips:本文以本文撰写时的Go语言最新版本,也就是go.1.19.2版本为例。Linux发行版本使用Ubuntu22.04.1LTS为例来做演示。安装C工具Go的工具链是用C语言编写......
  • 1_hadoop入门
    内容大纲:1.Hadoop架构详解大数据概述大数据发展史 //谷歌的3驾马车Hadoop的分类 //Apache社区版,Cloudera商业版(CDH版)应用场景特点Hadoop的架构图//Hadoop1.X......
  • Python if语句嵌套(入门必读)
    前面章节中,详细介绍了3种形式的条件语句,即if、ifelse和ifelifelse,这3种条件语句之间可以相互嵌套。例如,在最简单的if语句中嵌套ifelse语句,形式如下:if表达......
  • Python循环结构中else用法(入门必读)
    Python 中,无论是while循环还是for循环,其后都可以紧跟着一个else代码块,它的作用是当循环条件为False跳出循环时,程序会最先执行else代码块中的代码。以while循......
  • Python赋值运算符(入门必读)
    赋值运算符用来把右侧的值传递给左侧的变量(或者常量);可以直接将右侧的值交给左侧的变量,也可以进行某些运算后再交给左侧的变量,比如加减乘除、函数调用、逻辑运算等。Python......
  • 【Nuxt3从入门到实战】第三啪:巧用布局模板,高效开发从这里开始!
    前言大家好,我是村长,欢迎关注我的公众号村长学前端和B站Young村长!上一篇写了nuxt3路由系统,我们试用了两个重要功能:​​动态路由​​​和​​嵌套路由​​。体验便捷的同时,当......
  • 【Nuxt3从入门到实战】第二啪:约定路由用起来可真爽啊!
    前言大家好,我是村长,欢迎关注我的公众号村长学前端。最近在与DevUI团队一起做直播,给大家分享VueDevUI开源组件库的建设,欢迎大家关注我的B站Young村长!上一讲写了最小nuxt3应......