首页 > 其他分享 >KLC 数点学习笔记

KLC 数点学习笔记

时间:2024-07-31 21:28:35浏览次数:16  
标签:KLC int 值域 rep 数点 笔记 100010

KLC 数点由 KLC 大神在模拟赛中发明。

其算法复杂度与答案值域大小挂钩。

其能解决的问题一般有着如下的特点:给定一个序列,每次询问一个区间有多少个子区间满足什么性质,数据随机生成。

其算法流程为:

  1. 通过某种方法预处理出所有满足性质的子区间

  2. 将得到的区间表示在二维平面上

  3. 将询问离线,转化为二维数点,使用扫描线解决

其答案依赖于期望分析。

例题:

给定一个长度为 \(n\) 的数列,每次询问区间 \([l, r]\) 中子区间是值域连续段的个数, \(q\) 次询问。数据随机生成(注:原题没有该性质,但是仍可过,为保证算法正确性,在这里放了修改版)

考虑 KLC 数点,期望分析容易得到长度为 \(2\) 的值域连续段约有 \(O (1)\) 个,长度增加时出现次数更少,长度为 \(1\) 的值域连续段显然有 \(n\) 个,那么总共约有 \(O (n)\) 个,总复杂度为 \(O ( log n)\).

代码:

#include <bits/stdc++.h>
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; i++)
#define per(i, l, r) for (int i = l; i >= r; i--)
using namespace std;
int f[100010][30], g[100010][30], a[100010], ans[100010], n, q, l, r;
vector<array<int, 4> > v[100010];
struct BIT {
	int tree[100010];
	int lowbit(int x) { return x & (-x); }
	void modify(int u, int d) {
		while (u <= n) {
			tree[u] += d;
			u += lowbit(u);
		}
	}
	int query(int u) {
		int res = 0;
		while (u) {
			res += tree[u];
			u -= lowbit(u);
		}
		return res;
	}
}bit;
int findMin(int l, int r) {
	int s = log2(r - l + 1);
	return min(f[l][s], f[r - (1 << s) + 1][s]);
}
int findMax(int l, int r) {
	int s = log2(r - l + 1);
	return max(g[l][s], g[r - (1 << s) + 1][s]);
}
signed main() {
	// freopen("cat.in", "r", stdin);
	// freopen("cat.out", "w", stdout);
	cin >> n;
	rep (i, 1, n) {
		cin >> a[i];
		f[i][0] = a[i];
		g[i][0] = a[i];
	}
	rep (j, 1, log2(n)) {
		for (int i = 1; i + (1 << j) - 1 <= n; i++) {
			f[i][j] = min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
			g[i][j] = max(g[i][j - 1], g[i + (1 << (j - 1))][j - 1]);
		}
	}
	rep (i, 1, n) {
		// v[i].push_back({0, i, 1, 0});
		rep (j, i + 1, n) {
			int mmin = findMin(i, j), mmax = findMax(i, j);
			if (mmax - mmin + 1 == (j - i + 1)) {
				v[i].push_back({0, j, 1, 0});
			} else {
				j = mmax - mmin + i - 1;
			}
		}
	}
	cin >> q;
	rep (i, 1, q) {
		cin >> l >> r;
		v[l - 1].push_back({1, l, r, -i});
		v[r].push_back({1, l, r, i});
		ans[i] = r - l + 1;
	}
	rep (i, 1, n) {
		for (auto j:v[i]) {
			if (j[0]) {
				int id = 0, val = 0;
				if (j[3] > 0) id = j[3], val = 1;
				else id = -j[3], val = -1;
				// cout << id << " " << bit.query(j[2]) - bit.query(j[1] - 1) << "\n";
				ans[id] += (bit.query(j[2]) - bit.query(j[1] - 1)) * val;
			} else {
				bit.modify(j[1], j[2]);
			}
		}
	}
	rep (i, 1, q) {
		cout << ans[i] << "\n";
	}
}

标签:KLC,int,值域,rep,数点,笔记,100010
From: https://www.cnblogs.com/IANYEYZ/p/18335488

相关文章

  • 笔记:从Aurora 8b/10b 到Aurora 64b/66b (一):64b/66b 基本知识
    参考搬运:https://mp.weixin.qq.com/s/ZSNyjpZpimjyxyO9riIRNQAurora64B/66B(xilinx.com)https://docs.amd.com/r/en-US/pg074-aurora-64b66b8/10:SATASRIO64/66:10G以太网值得注意:64b/66b编码在多LANE模式下,EOF(T)仅在一个LANE上出现;介绍8B10B的开销比较大,每传输10位数......
  • 【学习笔记】KMP
    【学习笔记】KMP因为字符串对我太抽象了,所以只能以水的心态写这个KMP。感觉考到字符串的题肯定要崩。以下均规定字符串\(S\)以下标0开头。前缀函数:给定一个长度为\(n\)的字符串\(S\),其前缀函数被定义为一个长度为\(n\)的数组\(\pi\)。简单来说\(\pi[i]\)就是,子......
  • 后缀数组学习笔记
    前言后缀数组(SuffixArray,简称SA)是一种解决某些字符串问题的常用工具。解决这些字符串问题时,经常用后缀数组对问题进行一定的转化成其它的模型,然后套用那个模型的解决方法加以解决原问题。附题单约定本文做以下约定:本文撰写时间跨度较大,有些符号会出现正体、斜体混用的情......
  • MySQL 学习笔记 进阶(锁 下,InnoDB引擎 上)
    锁 锁-表级锁-表锁介绍表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM,InnoDB,BDB等存储引擎中。对于表级锁,主要分为以下三类:表锁元数据锁(metadatalock,MDL)意向锁表锁对于表锁,分为两类:表共享读锁(readlock)表独占写锁(write......
  • 扩展 BSGS 学习笔记
    在之前,我们学习了BSGS。设有\(a,b,m\),且\((a,m)\ne1\),求解:\[a^x\equivb\pmodm\]这玩意如何求解?把它变成BSGS能做的形式不就行了!具体的,设\(d_1=(a,m)\),若\(d_1\not|b\)则方程无解。否则我们可以得到:\[\dfrac{a}{d_1}\cdota^{x-1}\equiv\dfrac{b}{d_1}\pmod{\d......
  • 【复健】LCA复健笔记
    LCA复健笔记展开目录目录LCA复健笔记什么是LCA怎么求LCA暴力求LCA倍增优化应用场景不适合的应用场景什么是LCA最近公共祖先/最深公共祖先,顾名思义,两个点的公共祖先中离它们最近/深度最大的那个。怎么求LCA这里使用倍增优化算法,因为之前看不懂所以我觉得应该补一下......
  • 服务注册中心+配置中心-Nacos-微服务核心组件【分布式微服务笔记07】
    服务注册中心+配置中心-Nacos-微服务核心组件【分布式微服务笔记07】服务注册中心+配置中心-NacosNacos有两大功能:注册中心[替代Eureka]+配置中心[替代Config]架构理论基础:CAP理论(支持AP【高可用、分区容错性】和CP【分区容错性和数据一致性】,可以切换)Nacos结构......
  • 【学习笔记】Matlab和python双语言的学习(主成分分析法)
    文章目录前言一、主成分分析法1.主成分分析法简介2.主成分分析法原理3.主成分分析法思想4.PCA的计算步骤二、代码实现----Matlab三、代码实现----python总结前言通过模型算法,熟练对Matlab和python的应用。学习视频链接:https://www.bilibili.com/video/BV1EK41187......
  • git学习笔记1
    记录学习过程:git是如何运行工作的,先把文件从工作区传输到暂存区,之后再从暂存区传输到本地仓库git仓库的初始化,在需要的文件夹中右键鼠标"OpenGitBashHere",然后输入gitinit:git把文件先存放到暂存区之后git才能把文件存放到本地仓库可以查看当前git文件的状态,如果在......
  • Living-Dream 系列笔记 第70期
    登神长阶!P1272&P1273请查阅往期笔记,此处不再赘述。其中P1273我们学到了定义更好求解的状态(一般是转化为价值,如本题),再通过枚举求解最终答案。P8625容易发现你选出的\(S\)一定是一个子树。然后这题就变成最大子树和了。关于最大子树和那题,请查阅往期笔记,此处不再赘述。......