【无码专区13】最小公倍数(线段树)

因为只有std,没有自我实现,所以是无码专区

主要是为了训练思维能力

my idea顾名思义,记录了我的整个思维过程,以及自己部分实现细节口胡,还有期望分数

solution才是dls正解,但是因为只有潦草几句,所以大部分会有我自己基于正解上面的算法实现过程,可能选择的算法跟std中dls的实现不太一样。

std可能也会带有博主自己的注释。


problem

nnn 个数,其表示为 2ai⋅3bi2^{a_i}·3^{b_i}2ai3bi,给定 ai,bia_i,b_iai,bi

对于所有的非空子集,求出它们的最小公倍数,并求和。

答案对 1e9+71e9+71e9+7 取模。

测试点编号n≤n\lenai,bi≤a_i,b_i\leai,bi
1−21-21220202010910^9109
3−43-43410310^310310910^9109
5−65-65610510^510510310^3103
7−107-1071010510^510510910^9109

my idea

读完题就直接思考具有特殊性质的数据点,因为往往这种数据点的算法就是正解最朴素的原始样子。有价值的题都会这么设计部分分。某些毒瘤题呃呃呃

n≤103n\le 10^3n103 应该是与 n2n^2n2 挂钩的算法。

大概是枚举子集的最小值和最大值,强制入选,然后二维数点中间所有可以选择的数。为了避免算重,相同值的点还得强制规定一个大小,比如编号。

ai,bi≤103a_i,b_i\le 10^3ai,bi103 本质上与上面差不多。

只不过是从因子的幂次角度入手枚举。

枚举最大值的 a,ba,ba,b,二维数点所有 ai≤a,bi≤ba_i\le a,b_i\le baia,bib 的点,考虑是否选择。

同样为了避免算重,也得规定第三排序法则。

以上只是粗略的想法,并未细想。因为这个时候发现上面的做法其实是可以做正解的。

2a,3b2^a,3^b2a,3b 是相互独立的,可分开计算。

将所有数按 aaa 幂次大小升序排序后。

考虑枚举第 iii 个数的 aaa 作为最小公倍数的 aaa

显然,子集内的其余元素只能从 1≤j<i1\le j<i1j<i 里面选。

bbb 建立权值线段树,维护元素个数。

为了去重,强制枚举的数必选,那么最小公倍数 bbb 的至少是 bib_ibi

直接线段树上查一段区间作为作为最小公倍数 bbb 的答案。

具体而言:

线段树的叶子节点 xxx 维护的是 bj≤x,1≤j<ib_j\le x,1\le j<ibjx,1j<ijjj 的个数,假设为 ccc 个。

一个叶子节点如果是最后选的子集数的最小公倍数的 bbb 的话。

那么可能的子集为 2c−12^{c-1}2c1 个,−1-11 是因为必须要求 bj=xb_j=xbj=xjjj 中强制被选一个,这样才会有 bjb_jbj,否则会假掉。

一个点对答案的贡献就是 2c−1∗x2^{c-1}*x2c1x,此时必须保证有至少一个 bj=xb_j=xbj=x 才行。

所以一个点还要维护一个标记 fff,表示是否有至少一个 jjj 满足 bj=xb_j=xbj=x

那么一个点对答案的贡献应该是 2c−1∗x∗f2^{c-1}*x*f2c1xf

对于枚举的 iii 而言,算出来的贡献为 2ai∗2^{a_i}*2ai 线段树查询区间 [bj,MaxB][b_j,MaxB][bj,MaxB]

注意到,这个形式意味着还要对 bbb 进行离散化处理。

因为 iii 能让 bib_ibi 的线段树对应节点 f=1f=1f=1,而这之前可能是 f=0f=0f=0

所以要先修改再查询。

修改根据节点维护信息,对应的应是区间修改 [1,bi][1,b_i][1,bi],且特殊的, bib_ibifff 要置为 111

所以可以拆成区间修改 [1,bi)[1,b_i)[1,bi) 和单点修改 bib_ibi

懒标记一旦增加,相当于是多了一个个数,幂次 +1+1+1,拆出来变成外部 ×2\times 2×2

2lazy⋅(2c1∗x1∗f1+2c2∗x2∗f2+...+)2^{lazy}·(2^{c_1}*x_1*f_1+2^{c_2}*x_2*f_2+...+)2lazy(2c1x1f1+2c2x2f2+...+)

时间复杂度为 O(nlog⁡n)O(n\log n)O(nlogn)


solution

首先不妨设 ai,bia_i,b_iai,bi 两两不同。

考虑枚举集合中 bib_ibi 最大的元素,将所有 bj<bib_j<b_ibj<bi 的元素按 aja_jaj 从小到大排序。

不妨记作 a1′,a2′,...,ai−1′a_1',a_2',...,a_{i-1}'a1,a2,...,ai1,那么会有 2i−12^{i-1}2i1 个子集,最大值是 ai−1′a_{i-1}'ai1

考虑将 aia_iai 加入后,所有最大值 <ai<a_i<ai 的子集,最大值都变成了 aia_iai,剩下的子集不变。

aia_iai 加入到上面的有序序列后,所有比 aia_iai 大的元素排名都会 +1+1+1,对应的子集个数会翻倍。

问题等价于区间乘 222 以及区间求和,线段树维护。

就是my idea类似的思想,yeah我做出来了!


std

#include <bits/stdc++.h>
#define ls(x) (x << 1)
#define rs(x) ((x << 1) | 1)
#define LL long long
using namespace std;
const int maxn = 100010;
const LL mod = 1000000007;struct node {int x, y, rank;
};bool cmp1(node x, node y) {return x.x == y.x ? x.y < y.y : x.x < y.x;
}bool cmp2(node x, node y) {return x.y == y.y ? x.x < y.x : x.y < y.y;
}
node a[maxn];struct SegementTree {LL sum, cnt, lz;
};
SegementTree tr[maxn * 4];LL qpow(LL x, LL y) {LL ans = 1;for (; y; y >>= 1) {if (y & 1)ans = (ans * x) % mod;x = (x * x) % mod;}return ans;
}void pushup(int x) {tr[x].sum = (tr[ls(x)].sum + tr[rs(x)].sum) % mod;tr[x].cnt = (tr[ls(x)].cnt + tr[rs(x)].cnt) % mod;
}void maintain(int x, int y) {tr[x].sum = (tr[x].sum * qpow(2, y)) % mod;tr[x].lz += y;
}void pushdown(int x) {if (tr[x].lz) {if (tr[ls(x)].cnt)maintain(ls(x), tr[x].lz);if (tr[rs(x)].cnt)maintain(rs(x), tr[x].lz);tr[x].lz = 0;}
}void build(int x, int l, int r) {if (l == r) {tr[x].sum = tr[x].cnt = 0;return;}int mid = (l + r) >> 1;build(ls(x), l, mid);build(rs(x), mid + 1, r);pushup(x);
}void update_cnt(int x, int l, int r, int pos, int y, int z) {if (l == r) {tr[x].cnt = 1;tr[x].sum = (qpow(2, y) * qpow(2, z)) % mod;return;}pushdown(x);int mid = (l + r) >> 1;if (pos <= mid)update_cnt(ls(x), l, mid, pos, y, z);elseupdate_cnt(rs(x), mid + 1, r, pos, y, z);pushup(x);
}void update_sum(int x, int l, int r, int ql, int qr) {if (l >= ql && r <= qr) {tr[x].lz++;tr[x].sum = (tr[x].sum * 2) % mod;return;}pushdown(x);int mid = (l + r) >> 1;if (ql <= mid)update_sum(ls(x), l, mid, ql, qr);if (qr > mid)update_sum(rs(x), mid + 1, r, ql, qr);pushup(x);
}LL query_cnt(int x, int l, int r, int ql, int qr) {if (l >= ql && r <= qr) {return tr[x].cnt;}int mid = (l + r) >> 1;pushdown(x);LL ans = 0;if (ql <= mid)ans += query_cnt(ls(x), l, mid, ql, qr);if (qr > mid)ans += query_cnt(rs(x), mid + 1, r, ql, qr);return ans;
}LL query_sum(int x, int l, int r, int ql, int qr) {if (l >= ql && r <= qr) {return tr[x].sum;}int mid = (l + r) >> 1;LL ans = 0;pushdown(x);if (ql <= mid)ans += query_sum(ls(x), l, mid, ql, qr);if (qr > mid)ans += query_sum(rs(x), mid + 1, r, ql, qr);return ans % mod;
}int main() {freopen("lcm.in", "r", stdin);freopen("lcm.out", "w", stdout);int n;while (~scanf("%d", &n)) {for (int i = 1; i <= n; i++) {scanf("%d%d", &a[i].x, &a[i].y);}sort(a + 1, a + 1 + n, cmp1);for (int i = 1; i <= n; i++) {a[i].rank = i;}sort(a + 1, a + 1 + n, cmp2);build(1, 1, n);LL ans = 0;for (int i = 1; i <= n; i++) {LL tmp = query_cnt(1, 1, n, 1, a[i].rank);update_cnt(1, 1, n, a[i].rank, tmp, a[i].x);ans = (ans + query_sum(1, 1, n, a[i].rank, n) * qpow(3, a[i].y) % mod) % mod;if (a[i].rank != n)update_sum(1, 1, n, a[i].rank + 1, n);}printf("%lld\n", ans);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2021牛客暑期多校训练营2

2021牛客暑期多校训练营2 题号题目知识点AArithmetic ProgressionBCannonCDraw GridsDEr Ba GameEGas StationFGirlfriendGLeague of LegendsHOlefinIPenguinsbfsJProduct of GCDsKStackLWeChat Walk

P6772 [NOI2020] 美食家(矩阵快速幂)

前言 无能狂怒。 见过甚至写过博客的trick&#xff0c;但就是想不起来了。 解析 做法1 设 ft,xf_{t,x}ft,x​ 表示 t 时刻在 x 的最大价值。 直接转移即可&#xff0c;时间复杂度 O(T(nm))O(T(nm))O(T(nm))&#xff0c;期望得分 40 分。 结合无脑转圈的 A 性质&#xff0c;…

C# .net 中 Timeout 的处理及遇到的问题

C# 中 Timeout 的处理前言最近在项目中要实现一个功能&#xff0c;是关于 Timeout 的&#xff0c;主要是要在要在 TCP 连接建立的时间 和 整个请求完成的时间&#xff0c;在这两个时间层面上&#xff0c;如果超出了设置的时间&#xff0c;就抛出异常&#xff0c;程序中断。研究…

[CodeJam 2019 Round 3] Rancake Pyramid(笛卡尔树)

CodeJam 2019 Round 3 Rancake Pyramidproblemsolutioncodeproblem 神奈子是个很爱打麻将的老婆婆&#xff0c;有一天她把她的麻将放成了 nnn 堆&#xff0c;第 iii 堆的高度为 aia_iai​ 。 因为她很喜欢风&#xff0c;所以她用风吹倒了最左边的 LLL 堆麻将和最右边的 RRR 堆…

Harbour.Space Scholarship Contest 2021-2022 (open for everyone, rated, Div. 1 + Div. 2)

Harbour.Space Scholarship Contest 2021-2022 (open for everyone, rated, Div. 1 Div. 2) 题号题目知识点ADigits Sum签到BReverse String思维CPenalty思维DBackspace逆向思维EPermutation Shift置换群FPairwise ModuloGCommon Divisor GraphHXOR and DistanceIStairs cf15…

模板:全局平衡二叉树

所谓全局平衡二叉树&#xff0c;就是在全局来看都很平衡的二叉树。 &#xff08;逃 前言 这个引言倒是实话&#xff08;雾 可以把一些本来只能用树剖两个 log 做的问题在单log 时间复杂度解决。 修改通常来说只能支持单点修改。 查询解决链上问题或者全局问题更为方便&#x…

[CodeJam 2021 Round 3] Square Free(调整法 / 字典序最小解网络流)

CodeJam 2021 Round3 Square Freeproblemsolutioncodecode-stdproblem 神奈子是个很爱打麻将的老婆婆&#xff0c;有一天她把她的麻将放进了一个 nmn\times mnm 的网格图里&#xff0c;每个麻将可以左斜着放入网格中&#xff08;如 / &#xff09;&#xff0c;也可以右斜着&am…

P6773 [NOI2020] 命运(dp、线段树合并)

前言 一道看起来很毒瘤但其实还算小清新的题&#xff1f; 理解后感觉其实并没有那么难。 暴力分非常足&#xff0c;好评。 奇妙的线段树合并技巧增加了。 解析 解法1 你是怎么手玩的样例一&#xff1f; 大部分&#xff08;比如我&#xff09;都是容斥吧。 把手玩的方法搬到…

ConsurrentDictionary并发字典知多少?

在上一篇文章你真的了解字典吗?一文中我介绍了Hash Function和字典的工作的基本原理.有网友在文章底部评论,说我的Remove和Add方法没有考虑线程安全问题.https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?redirectedfromMSDN&viewn…

[luogu 4292][bzoj 1758][WC2010] 重建计划(点分治 + dp + 单调队列优化 + 启发式合并)

[WC2010]重建计划problemsolutioncodeproblem 洛谷指路 solution 一看那个道路平均价值的式子&#xff1a;AvgValue∑e∈Sv(e)∣S∣\text{AvgValue}\frac{\sum_{e\in S}v(e)}{|S|}AvgValue∣S∣∑e∈S​v(e)​ 就是 0/1分数规划 的样子。 所以考虑二分最终的答案 midmidmid…

cf1553C. Penalty

cf1553C. Penalty 题意&#xff1a; 有十轮点球&#xff0c;两个队伍轮流进行&#xff0c;1表示进&#xff0c;0表示不进&#xff0c;&#xff1f;表示未知&#xff0c;如果比赛没有了悬念将直接结束。现在让你预测一个情况&#xff0c;使得进行的轮数最少。裁判在决定停止点…

ASP.NET Core 基于JWT的认证(二)

上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍&#xff0c;这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt在 .Net Core 上的实际运用。.Net Core 2.2Visual Studio 2017ASP.NET Core WebAPI2在上一篇文章中&#xff0c;我们详细的介绍了JWT的知识&#xff0c;这…

P6774 [NOI2020] 时代的眼泪(分块)

前言 看到题目名&#xff1a;别骂了别骂了。 一道很中规中矩的YNOI吧。 卡在整块对整块的贡献上了。 这也确实算是本题最不好做的部分了。 前置知识&#xff1a;Yuno loves sqrt technology I 解析 区间逆序对加强版&#xff1f;很难不想到两道 YLST。 然而多了两维限制&a…

[NOIP2021] 数列(计数dp)

solution f[i][j][k][num][p]:2pf[i][j][k][num][p]:2^pf[i][j][k][num][p]:2p 选择了 iii 个&#xff0c;前 p−1p-1p−1 位 (202p−1)(2^0~2^{p-1})(20 2p−1) 已经选了jjj个&#xff0c;低位向高位进位上来 kkk&#xff0c;前 ppp 位已经确定有 numnumnum 个位置为 111&…

Xor sum HDU - 6955

Xor sum HDU - 6955 题意&#xff1a; 给定一个长度为n的整数序列&#xff0c;求其XOR和不小于k的最短连续子序列。 如果有多个相同长度的连续子序列&#xff0c;则打印具有最小左端点的连续子序列。 如果没有连续的子序列开关XOR总和不小于k&#xff0c;只需打印“-1”。 …

模板:子序列自动机(字符串)

所谓子序列自动机&#xff0c;就是根据子序列建立的自动机。 &#xff08;逃&#xff09; 前言 小清新算法。 解析 和其他自动机类似的&#xff0c;我们希望子序列自动机能且只能接受原串的所有子序列。 考虑一个问题&#xff1a;给你一个串 T&#xff0c;如何判断它是否是…

Docker最全教程之Go实战,墙裂推荐(十九)

前言与其他语言相比&#xff0c;Go非常值得推荐和学习&#xff0c;真香&#xff01;为什么&#xff1f;主要是可以直接编译成机器代码&#xff08;性能优越&#xff0c;体积非常小&#xff0c;可达10来M&#xff0c;见实践教程图片&#xff09;而且设计良好&#xff0c;上手门槛…

[BZOJ3093][Fdu校赛2012] A Famous Game(不等概率)

problem BOZJ3093 solution 逆概率公式&#xff0c;即贝叶斯(Bayes)公式&#xff1a; 假设 B1,B2,...,BnB_1,B_2,...,B_nB1​,B2​,...,Bn​ 是 Ω\OmegaΩ 的一个分割&#xff0c;P(A)>0P(A)>0P(A)>0&#xff0c;则有 P(Bk∣A)P(ABk)P(A)P(Bk)P(A∣Bk)∑i1nP(Bi)…

Mod, Or and Everything HDU - 6950

Mod, Or and Everything HDU - 6950 题意&#xff1a; 给你一个n,问(n%1) or (n%2) or … or (n %n)的值 题解&#xff1a; 无论n为奇偶&#xff0c;定义m(n-1)/2&#xff0c; 我们发现n mod i<m&#xff0c;而当i<m时&#xff0c;有n mod (n-i) i ,于是就有n mod i …

你注意到 .Net Framework 和 .Net Core 中使用 Session 的区别了吗?

在测试一个例子时发现的问题&#xff0c;这个示例实现的功能是刷新页面也能保持表格锁定列的状态&#xff0c;先看下页面的完成效果&#xff1a;测试中发现&#xff0c;几乎相同的代码&#xff1a;在 FineUIMvc&#xff08;Net Framework&#xff09;下没有问题&#xff1a;htt…