LOJ 2958

线段树 + 类欧

主要矛盾就是$\sum\limits_{i = l}^{r}Ai \mod B$怎么做。

拆成前缀和相减的形式,有

$$\sum_{i = 0}^{r}(Ai \mod B) - \sum_{i = 0}^{l - 1}(Ai \mod B)$$

我们知道

$$a \mod b = a - \left \lfloor \frac{a}{b} \right \rfloor b$$

那么

$$\sum_{i = 0}^{n}Ai \mod B = \sum_{i = 0}^{n} Ai - \left \lfloor \frac{Ai}{B} \right \rfloor B = \frac{An(n + 1)}{2} - B\sum_{i = 0}^{n}\left \lfloor \frac{Ai}{B} \right \rfloor$$

后面那个东西就是类欧模板中的$f(A, 0, B, n)$。

还有一件事情:$10^9 * 2 * 10^9 / 2 * 10^6 = 10^{24} > long\ long$,所以我写了一个$\text{__int128}$。

因为标记一定要下传,所以似乎不能动态开点而需要离散,但是离散之后注意到线段树一个结点左右儿子可能并不是连续的。

举个栗子,假如我们离散完之后的序列是${1, 5, 7, 9}$,那么一号结点对应的区间是$[1, 9]$,而它的左儿子是$[1, 5]$,右儿子是$[7, 9]$,中间还有一段$[6, 6]$的空缺。所以我们在$up$和算答案的时候需要考虑这段空缺的贡献(可能是我线段树没学好qwq)。

这样子的话效率就很迷人了。

时间复杂度$O(qlog^2n)$。

Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef __int128 ILL;const int N = 1e5 + 5;int n, qn, tot = 0, buc[N];struct Options {int op, l, r, A, B;
} q[N];namespace Fread {const int L = 1 << 15;char buffer[L], *S, *T;inline char Getchar() {if(S == T) {T = (S = buffer) + fread(buffer, 1, L, stdin);if(S == T) return EOF;}return *S++;}template <class T> inline void read(T &X) {char ch; T op = 1;for(ch = Getchar(); ch > '9' || ch < '0'; ch = Getchar())if(ch == '-') op = -1;for(X = 0; ch >= '0' && ch <= '9'; ch = Getchar()) X = (X << 1) + (X << 3) + ch - '0'; X *= op;}} using namespace Fread;   namespace Fwrite {const int L = 1 << 15;char buf[L], *pp = buf;void Putchar(const char c) {if(pp - buf == L) fwrite(buf, 1, L, stdout), pp = buf;*pp++ = c;}template<typename T>void print(T x) {if(x < 0) {Putchar('-');x = -x;}if(x > 9) print(x / 10);Putchar(x % 10 + '0');}void fsh() {fwrite(buf, 1, pp - buf, stdout);pp = buf;}template <typename T>inline void write(T x, char ch = 0) {print(x);if (ch != 0) Putchar(ch);fsh();}} using namespace Fwrite;namespace LikeGcd {ILL solve(ILL a, ILL b, ILL c, ILL n) {if (!a) return (b / c) * (n + 1);if (a >= c || b >= c) return (a / c) * n * (n + 1) / 2 + (b / c) * (n + 1) + solve(a % c, b % c, c, n);if (a < c && b < c) {ILL m = (a * n + b) / c;return n * m - solve(c, c - b - 1, a, m - 1);}return 0;}
}namespace SegT {struct Node {int st, A, B;ll sum;bool tag;} s[N << 2];#define lc p << 1#define rc p << 1 | 1#define mid ((l + r) >> 1)#define st(p) s[p].st#define A(p) s[p].A#define B(p) s[p].B#define sum(p) s[p].sum#define tag(p) s[p].taginline ll calc(int p, int st, int en) {
//        int st = st(p), en = st(p) + buc[r] - buc[l];if (!B(p)) return 0;ILL res = 0;res += (ILL)A(p) * (ILL)(st + en) * (ILL)(en - st + 1) / (ILL)2;res -= (ILL)B(p) * (LikeGcd :: solve(A(p), 0, B(p), en) - LikeGcd :: solve(A(p), 0, B(p), st - 1));return 1LL * res;}inline void up(int p, int l, int r) {sum(p) = sum(lc) + sum(rc);if (buc[mid] + 1 != buc[mid + 1]) {sum(p) += calc(p, st(p) + buc[mid] + 1 - buc[l], st(p) + buc[mid + 1] - 1 - buc[l]);}}inline void down(int p, int l, int r) {if (!tag(p)) return;st(lc) = st(p), st(rc) = st(p) + buc[mid + 1] - buc[l];A(lc) = A(rc) = A(p);B(lc) = B(rc) = B(p);tag(lc) = tag(rc) = 1;sum(lc) = calc(lc, st(lc), st(lc) + buc[mid] - buc[l]);sum(rc) = calc(rc, st(rc), st(rc) + buc[r] - buc[mid + 1]);tag(p) = 0;}void modify(int p, int l, int r, int x, int y, int A, int B) {if (x <= l && y >= r) {tag(p) = 1;st(p) = buc[l] - buc[x] + 1, A(p) = A, B(p) = B;sum(p) = calc(p, st(p), st(p) + buc[r] - buc[l]);return;}down(p, l, r);if (x <= mid) modify(lc, l, mid, x, y, A, B);if (y > mid) modify(rc, mid + 1, r, x, y, A, B);if (buc[mid + 1] != buc[mid] + 1) {if (buc[x] <= buc[mid] + 1 && buc[y] >= buc[mid + 1] - 1) {A(p) = A, B(p) = B;st(p) = buc[l] - buc[x] + 1;}}up(p, l, r);}ll query(int p, int l, int r, int x, int y) {if (x <= l && y >= r) return sum(p);down(p, l, r);ll res = 0;if (x <= mid) res += query(lc, l, mid, x, y);if (y > mid) res += query(rc, mid + 1, r, x, y);if (buc[mid + 1] != buc[mid] + 1) {if (buc[y] >= buc[mid] + 1 && buc[x] <= buc[mid + 1] - 1) {int ln = max(buc[mid] + 1, buc[x]);int rn = min(buc[mid + 1] - 1, buc[y]);res += calc(p, st(p) + ln - buc[l], st(p) + rn - buc[l]);            } }return res;}void ddd(int p, int l, int r) {if (l == r) return;down(p, l, r);ddd(lc, l, mid), ddd(rc, mid + 1, r);}} using namespace SegT;int main() {
/*    #ifndef ONLINE_JUDGEfreopen("input.txt", "r", stdin);#endif      */read(n), read(qn);for (int i = 1; i <= qn; i++) {read(q[i].op), read(q[i].l), read(q[i].r);buc[++tot] = q[i].l, buc[++tot] = q[i].r;if (q[i].op == 1) read(q[i].A), read(q[i].B);}sort(buc + 1, buc + 1 + tot);tot = unique(buc + 1, buc + 1 + tot) - buc - 1;//    for (int i = 1; i <= tot; i++)
//        printf("%d%c", buc[i], " \n"[i == tot]);     for (int i = 1; i <= qn; i++) {q[i].l = lower_bound(buc + 1, buc + 1 + tot, q[i].l) - buc;q[i].r = lower_bound(buc + 1, buc + 1 + tot, q[i].r) - buc;}for (int i = 1; i <= qn; i++) {if (q[i].op == 1) modify(1, 1, tot, q[i].l, q[i].r, q[i].A, q[i].B);else write(query(1, 1, tot, q[i].l, q[i].r), '\n');/*        ddd(1, 1, tot);printf("\n");for (int j = 1; j <= 9; j++) printf("%d %lld %d %d %d\n", j, sum(j), A(j), B(j), st(j));    */}return 0;
}

View Code

转载于:https://www.cnblogs.com/CzxingcHen/p/10388319.html

Luogu 4433 [COCI2009-2010#1] ALADIN相关推荐

  1. POJ 1703 Find them, Catch them(并查集高级应用)

    POJ 1703 Find them, Catch them(并查集高级应用) 手动博客搬家:本文发表于20170805 21:25:49, 原地址https://blog.csdn.net/sunc ...

  2. luogu P1774 最接近神的人_NOI导刊2010提高(02)

    题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门上方用古代文写着"神的殿堂".小FF猜 ...

  3. Luogu P4859「已经没有什么好害怕的了」

    以前开过一遍这题,以为很难没刚下去 今天$ review$一遍分析了一下感觉也还好 luogu 4859 题意:给定长度为$ n \leq 2000$的数组$ A,B$求完全匹配使得$A>B$的 ...

  4. 【DP】字串距离(luogu 1279)

    字串距离 luogu 1279 题目大意 给出两个字符串,让你加上若干空格,使其长度相同 对于第i位,如果都是字母那代价就是ASCII码的差值,如果一个是字母那就是k,如果没有一个是字母那就是0,让你 ...

  5. 【数学】拉格朗日插值(luogu 4781/金牌导航 拉格朗日插值-1)

    拉格朗日插值 luogu 4781 金牌导航 拉格朗日插值-1 题目大意 给出n个点,让你确定经过这n个点且不超过n-1次的方程,现在给出k,让你求出其函数值 样例#1 输入样例#1 3 100 1 ...

  6. 【斜率优化】仓库建设(luogu 2120)

    仓库建设 luogu 2120 题目大意 有一个斜坡,上面有n个工厂(山顶是1,山脚是nnn,工厂都是漏填),上面有pip_ipi​个货物,和工厂1的距离为x1x_1x1​ 现在有一场大雨,你可以在某 ...

  7. 简介SharePoint 2010 14 Hive文件夹

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u012025054/article/details/36018873 简介SharePoint 20 ...

  8. luogu P1549 棋盘问题(2) 题解

    luogu P1549 棋盘问题(2) 题解 题目描述 在\(N * N\)的棋盘上\((1≤N≤10)\),填入\(1,2,-,N^2\)共\(N^2\)个数,使得任意两个相邻的数之和为素数. 例如 ...

  9. [Luogu] 选学霸

    https://www.luogu.org/problemnew/show/P2170 并查集+DP #include <iostream> #include <cstring> ...

最新文章

  1. java 移动支付接口开发,移动支付平台间接口报文解析技术核心架构实现、及平台交易处理项目全程实录教程...
  2. python论坛哪些好-好的python论坛
  3. 最好用的20个数据可视化工具(一)
  4. 使用JS制作一个鼠标可拖的DIV(三)——移动带图片DIV
  5. Android 编码规范:(七)避免使用终结方法
  6. nginx简介--理解nginx配置/模块/openresty
  7. 【转】Elasticsearch+Django搜索引擎(二)
  8. 扇贝有道180927每日一句
  9. Eclipse安装包 百度网盘
  10. C语言的行指针和列指针
  11. 计算机网络(第七版)知识点总结第一章——概述
  12. mysql 监控_【MySQL】MySQL监控工具 mysql-monitor
  13. 海贼王最新漫画情报分析
  14. 网页播放器自定义倍速播放
  15. 网页优化(布局优化、图片优化)
  16. Android 尺寸转换器(适配各种屏幕)
  17. 最长递增子序列 O(NlogN)算法
  18. SVG—初识4之描边动画和路径动画
  19. 如何用matlab画负倒函数曲线,负倒描述函数
  20. 课题申报书范文_课题申报书范文.doc

热门文章

  1. Metashape(Photoscan)配置局域网集群的方式(存储于NAS)
  2. 区块链农产品溯源系统 北京鸿蒙,区块链特色农产品溯源平台解决方案
  3. 聊一聊bundle为啥会被设计成如此格式
  4. 对一个MEMO中的字段处理
  5. 庖丁解牛:Xshell连接虚拟机中的Linux时经常自动断开,断开之后还很难连接上
  6. delphi技术专题---获取网卡物理地址之NB30.pas单元TNCB详解以及源代码分享
  7. 下载centos下的工具包
  8. 复习JAVA高级部分
  9. 看华为eLTE-IoT如何联接高效工业物联网
  10. 我为什么从来不炒股?