zoukankan      html  css  js  c++  java
  • 猫树模板

    参考博客:
    http://immortalco.blog.uoj.ac/blog/2102
    https://www.cnblogs.com/Judge/p/10475728.html

    板题:
    https://www.luogu.com.cn/problem/P3865

    注意点:

    • 猫树的语处理的数组的存法:同一深度的区间互不相交,所以记二维数组,第一维是深度,第二维是位置。

    • 猫树的核心在于快速求lca,所以需要把线段树长度搞成(2^{tp}),这样(x)在线段树的编号就是(x+2^{tp}),两个点的lca就是树上编号的lcp,可以通过预处理(log_2)来快速处理。

    • 预处理的(log_2)数组必须是两倍于最大的(2^{tp}),因为当(x,y)相同时,会要求(log_2(x+2^{tp})),这个数是超过(2^{tp+1})的。

    Code:

    #include<bits/stdc++.h>
    #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
    #define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
    #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
    #define ll long long
    #define pp printf
    #define hh pp("
    ")
    using namespace std;
    
    #define gc getchar
    template<class T> void read(T &x) {
    	char c = ' '; int f = 1; x = 0;
    	while(c != '-' && (c < '0' || c > '9')) c = gc();
    	if(c == '-') c = gc(), f = -1;
    	for(; c >= '0' && c <= '9'; c = gc()) x = x * 10 + c - '0';
    	x *= f;
    }
    #define pc putchar
    template<class T> void write(T x) {
    	int d[30], d0 = 0;
    	if(!x) d[d0 = 1] = 0; else {
    		for(; x; x /= 10) d[++ d0] = x % 10;
    	}
    	while(d0) pc(d[d0 --] + '0');
    }
    
    const int N = (1 << 17) + 5;
    
    int lg2[N * 2];
    
    int n, m;
    int tp;
    
    int a[N];
    
    #define i0 i + i
    #define i1 i + i + 1
    
    int f[18][N];
    
    void dg(int i, int x, int y) {
    	int D = lg2[i];
    	if(x == y) {
    		f[D][x] = a[x];
    		return;
    	}
    	int m = x + y >> 1;
    	dg(i0, x, m); dg(i1, m + 1, y);
    	int v = 0;
    	fd(j, m, x) v = max(v, a[j]), f[D][j] = v;
    	v = 0;
    	fo(j, m + 1, y) v = max(v, a[j]), f[D][j] = v;
    }
    
    int main() {
    	lg2[0] = -1;
    	fo(i, 2, 1 << 18) lg2[i] = lg2[i / 2] + 1;
    	scanf("%d %d", &n, &m);
    	fo(i, 1, n) read(a[i]);
    	while(1 << (++ tp) <= n);
    	dg(1, 0, (1 << tp) - 1);
    	fo(ii, 1, m) {
    		int x, y; read(x); read(y);
    		int u = x + (1 << tp), v = y + (1 << tp);
    		int D = lg2[u >> (lg2[u ^ v] + 1)];
    		write(max(f[D][x], f[D][y])); pc('
    ');
    	}
    }
    
  • 相关阅读:
    string去除指定字符
    size_t和int
    size_t和int
    mysql默认密码的查找与修改
    mysql默认密码的查找与修改
    MYSQL安装报错 -- 出现Failed to find valid data directory.
    Windows下修改Git bash的HOME路径
    在windows安装配置Git开发环境
    Git 历险记
    Git 简易使用指南及补充
  • 原文地址:https://www.cnblogs.com/coldchair/p/13068735.html
Copyright © 2011-2022 走看看