【树状数组该回炉重造了】Codeforces Round #813 (Div. 2) E2. LCM Sum (hard version)

2023-11-19

参考题解

题意:
T T T 组数据,每组数据给定 l l l r r r
求有多少种 l c m ( i , j , k ) ≥ i + j + k lcm(i,j,k)\geq i+j+k lcm(i,j,k)i+j+k,其中 l ≤ i < j < k ≤ r l\leq i<j<k\leq r li<j<kr

数据范围: 1 ≤ T ≤ 1 0 5 , 1 ≤ l ≤ r ≤ 2 × 1 0 5 , l + 2 ≤ r 1\leq T\leq 10^5, 1\leq l\leq r\leq 2\times 10^5,l+2\leq r 1T105,1lr2×105,l+2r

题解:
仍然是正难则反,考虑 l c m ( i , j , k ) < i + j + k lcm(i,j,k)<i+j+k lcm(i,j,k)<i+j+k 的数量
开一个树状数组 t r tr tr t r [ i ] tr[i] tr[i] 用于维护三元组中 i , j , k i,j,k i,j,k的数量
具体是枚举 k k k

  • l c m ( i , j , k ) = k lcm(i,j,k)=k lcm(i,j,k)=k
    枚举 k k k 的因子,第一层枚举 i i i,第二层枚举 j j j
    经过计算双重枚举在 2 × 1 0 5 2\times10^5 2×105 范围内在 3 e 7 3e7 3e7 左右,时限为 3500 m s 3500ms 3500ms,实测跑 480 m s 480ms 480ms

  • l c m ( i , j , k ) = 2 k lcm(i,j,k)=2k lcm(i,j,k)=2k以下情况的证明

    第一种情况: i = 2 k 5 , j = 2 k 3 i=\frac{2k}{5},j=\frac{2k}{3} i=52k,j=32k
    第二种情况: i = k 2 , j = 2 k 3 i=\frac{k}{2},j=\frac{2k}{3} i=2k,j=32k

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N = 200010;
struct Node {
	int l, id;
};

vector<Node> a[N];
ll ans[N];
ll tr[N]; // 树状数组 tr[i] 表示以 i 开头的 (i,j,k)

const int MAXN = 200000;
const int MAXM = MAXN << 1; 
ll sum(int p) {
	ll res = 0;
	while (p > 0) {
		res += tr[p];
		p -= p & (-p);
	}
	return res;
}

void add(int p, ll x) {
	while (p <= MAXN) {
		tr[p] += x; 
		p += p & (-p);
	}
}

vector<int> fac[N];
int n;

int main()
{
	// 类似埃筛的 O(nlogn) 筛因子法
	for (int i = 1; i <= MAXN; ++i)
		for (int j = i * 2; j <= MAXN; j += i)
			fac[j].push_back(i);
	
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		int l, r;
		scanf("%d%d", &l, &r);
		a[r].push_back({l, i});
		ll x = r - l + 1;
		ans[i] = x * (x - 1) * (x - 2) / 6;
	}
	
	// 枚举 r,同时将这个 r 对应为 k 的所有的 (i, j, k) 累计到树状数组 tr[i] 中
	for (int r = 1; r <= MAXN; ++r) {
		for (int i = 0; i < fac[r].size(); ++i) {
			int x = fac[r][i];
			int cnt = 0;
			for (int j = i + 1; j < fac[r].size(); ++j) {
				int y = fac[r][j];
				if (r % x == 0 && r % y == 0) cnt += 1;
			}
			add(x, cnt);
		}
		
		// lcm(i,j,k)=2k, i=2k/5, j=2k/3
		if (r % 15 == 0) {
			int x = r / 5 * 2;
			int y = r / 3 * 2;
			add(x, 1);
		}
		// lcm(i,j,k)=2k, i=k/2, j=2k/3
		if (r % 6 == 0) {
			int x = r / 2;
			int y = r / 3 * 2;
			add(x, 1);
		}
		// 只统计 从 [l, r - 2] 内的 i 对应的方案数
		for(auto& u: a[r]) {
			ans[u.id] -= sum(r - 2) - sum(u.l - 1);
		}
	}
	
	for (int i = 1; i <= n; ++i) printf("%lld\n", ans[i]);
	
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【树状数组该回炉重造了】Codeforces Round #813 (Div. 2) E2. LCM Sum (hard version) 的相关文章

  • 如何在MVVM中管理多个窗口

    我知道有几个与此类似的问题 但我还没有找到明确的答案 我正在尝试深入研究 MVVM 并尽可能保持纯粹 但不确定如何在坚持模式的同时启动 关闭窗口 我最初的想法是向 ViewModel 发送数据绑定命令 触发代码来启动一个新视图 然后通过 X
  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • 如何避免情绪低落?

    我有一个实现状态模式每个状态处理从事件队列获取的事件 根据State因此类有一个纯虚方法void handleEvent const Event 事件继承基础Event类 但每个事件都包含其可以是不同类型的数据 例如 int string
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 如何将图像路径保存到Live Tile的WP8本地文件夹

    我正在更新我的 Windows Phone 应用程序以使用新的 WP8 文件存储 API 本地文件夹 而不是 WP7 API 隔离存储文件 旧的工作方法 这是我如何成功地将图像保存到 共享 ShellContent文件夹使用隔离存储文件方法
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • 将 unsigned char * (uint8_t *) 转换为 const char *

    我有一个带有 uint8 t 参数的函数 uint8 t ihex decode uint8 t in size t len uint8 t out uint8 t i hn ln for i 0 i lt len i 2 hn in i
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 控制到达非 void 函数末尾 -wreturn-type

    这是查找四个数字中的最大值的代码 include
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • 如何使用 std::string 将所有出现的一个字符替换为两个字符?

    有没有一种简单的方法来替换所有出现的 in a std string with 转义 a 中的所有斜杠std string 完成此操作的最简单方法可能是boost字符串算法库 http www boost org doc libs 1 46
  • 防止索引超出范围错误

    我想编写对某些条件的检查 而不必使用 try catch 并且我想避免出现 Index Out of Range 错误的可能性 if array Element 0 Object Length gt 0 array Element 1 Ob
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐