Luogu 4433 [COCI2009-2010#1] ALADIN
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 + ; int n, qn, tot = , buc[N]; struct Options {
int op, l, r, A, B;
} q[N]; namespace Fread {
const int L = << ; char buffer[L], *S, *T; inline char Getchar() {
if(S == T) {
T = (S = buffer) + fread(buffer, , L, stdin);
if(S == T) return EOF;
}
return *S++;
} template <class T>
inline void read(T &X) {
char ch; T op = ;
for(ch = Getchar(); ch > '' || ch < ''; ch = Getchar())
if(ch == '-') op = -;
for(X = ; ch >= '' && ch <= ''; ch = Getchar())
X = (X << ) + (X << ) + ch - '';
X *= op;
} } using namespace Fread; namespace Fwrite {
const int L = << ; char buf[L], *pp = buf; void Putchar(const char c) {
if(pp - buf == L) fwrite(buf, , L, stdout), pp = buf;
*pp++ = c;
} template<typename T>
void print(T x) {
if(x < ) {
Putchar('-');
x = -x;
}
if(x > ) print(x / );
Putchar(x % + '');
} void fsh() {
fwrite(buf, , pp - buf, stdout);
pp = buf;
} template <typename T>
inline void write(T x, char ch = ) {
print(x);
if (ch != ) Putchar(ch);
fsh();
} } using namespace Fwrite; namespace LikeGcd {
ILL solve(ILL a, ILL b, ILL c, ILL n) {
if (!a) return (b / c) * (n + );
if (a >= c || b >= c)
return (a / c) * n * (n + ) / + (b / c) * (n + ) + 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 - , a, m - );
}
return ;
}
} namespace SegT {
struct Node {
int st, A, B;
ll sum;
bool tag;
} s[N << ]; #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].tag inline ll calc(int p, int st, int en) {
// int st = st(p), en = st(p) + buc[r] - buc[l];
if (!B(p)) return ;
ILL res = ;
res += (ILL)A(p) * (ILL)(st + en) * (ILL)(en - st + ) / (ILL);
res -= (ILL)B(p) * (LikeGcd :: solve(A(p), , B(p), en) - LikeGcd :: solve(A(p), , B(p), st - ));
return 1LL * res;
} inline void up(int p, int l, int r) {
sum(p) = sum(lc) + sum(rc);
if (buc[mid] + != buc[mid + ]) {
sum(p) += calc(p, st(p) + buc[mid] + - buc[l], st(p) + buc[mid + ] - - 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 + ] - buc[l];
A(lc) = A(rc) = A(p);
B(lc) = B(rc) = B(p);
tag(lc) = tag(rc) = ;
sum(lc) = calc(lc, st(lc), st(lc) + buc[mid] - buc[l]);
sum(rc) = calc(rc, st(rc), st(rc) + buc[r] - buc[mid + ]);
tag(p) = ;
} void modify(int p, int l, int r, int x, int y, int A, int B) {
if (x <= l && y >= r) {
tag(p) = ;
st(p) = buc[l] - buc[x] + , 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 + , r, x, y, A, B);
if (buc[mid + ] != buc[mid] + ) {
if (buc[x] <= buc[mid] + && buc[y] >= buc[mid + ] - ) {
A(p) = A, B(p) = B;
st(p) = buc[l] - buc[x] + ;
}
} 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 = ;
if (x <= mid) res += query(lc, l, mid, x, y);
if (y > mid) res += query(rc, mid + , r, x, y);
if (buc[mid + ] != buc[mid] + ) {
if (buc[y] >= buc[mid] + && buc[x] <= buc[mid + ] - ) {
int ln = max(buc[mid] + , buc[x]);
int rn = min(buc[mid + ] - , 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 + , r);
} } using namespace SegT; int main() {
/* #ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif */ read(n), read(qn);
for (int i = ; 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 == ) read(q[i].A), read(q[i].B);
} sort(buc + , buc + + tot);
tot = unique(buc + , buc + + tot) - buc - ; // for (int i = 1; i <= tot; i++)
// printf("%d%c", buc[i], " \n"[i == tot]); for (int i = ; i <= qn; i++) {
q[i].l = lower_bound(buc + , buc + + tot, q[i].l) - buc;
q[i].r = lower_bound(buc + , buc + + tot, q[i].r) - buc;
} for (int i = ; i <= qn; i++) {
if (q[i].op == ) modify(, , tot, q[i].l, q[i].r, q[i].A, q[i].B);
else write(query(, , 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 ;
}
Luogu 4433 [COCI2009-2010#1] ALADIN的更多相关文章
- [Luogu P4180][BJWC 2010]严格次小生成树
严格次小生成树,关键是“严格”,如果是不严格的其实只需要枚举每条不在最小生成树的边,如果得到边权和大于等于最小生成树的结束就行.原理就是因为Kruskal非常贪心,只要随便改一条边就能得到一个非严格的 ...
- luogu P4385 [COCI2009]Dvapravca
传送门 我真的弱,正解都不会还打了个错的暴力 考虑平行线与x轴平行,那么可以按照y为第一关键字升序,x为第二关键字升序排序,然后合法的一段红点就是连续的一段,答案也就是最大的连续红色段 推广到一般情况 ...
- POJ 1703 Find them, Catch them(并查集高级应用)
手动博客搬家:本文发表于20170805 21:25:49, 原地址https://blog.csdn.net/suncongbo/article/details/76735893 URL: http ...
- [luogu]P1800 software_NOI导刊2010提高(06)[DP][二分答案]
[luogu]P1800 software_NOI导刊2010提高(06) 题目描述 一个软件开发公司同时要开发两个软件,并且要同时交付给用户,现在公司为了尽快完成这一任务,将每个软件划分成m个模块, ...
- Luogu P1801 黑匣子_NOI导刊2010提高(06)
P1801 黑匣子_NOI导刊2010提高(06) 题目描述 Black Box是一种原始的数据库.它可以储存一个整数数组,还有一个特别的变量i.最开始的时候Black Box是空的.而i等于0.这个 ...
- 【luogu P1774 最接近神的人_NOI导刊2010提高(02)】 题解
题目链接:https://www.luogu.org/problemnew/show/P1774 归并排序求逆序对. #include <cstdio> #define livelove ...
- 【luogu P1801 黑匣子_NOI导刊2010提高(06)】 题解
题目链接:https://www.luogu.org/problemnew/show/P1801 替罪羊树吼啊! #include <cstdio> #include <cstrin ...
- 【luogu P1807 最长路_NOI导刊2010提高(07)】 题解
题目链接:https://www.luogu.org/problemnew/show/P1807 求最大路?就是把权值取相反数跑最短路. #include <cstdio> #includ ...
- Luogu P1776 宝物筛选_NOI导刊2010提高(02)(多重背包模版)
传送门 多重背包板子题, 多重背包就是每种东西有好几个,可以把它拆分成一个一个的01背包 优化:二进制拆分(拆成1+2+4+8+16+...) 比如18=1+2+4+8+3,可以证明18以内的任何数都 ...
随机推荐
- 20145237 Exp2 后门原理与实践
20145237<网络对抗>Exp2 后门原理与实践 Windows获得Linux Shell 在Windows下,先使用ipconfig指令查看本机IP: 输入ncat.exe -l - ...
- Mac 使用ab性能测试工具
Mac 使用ab命令进行压测 1.在Mac中配置Apache ①启动Apache,打开终端 sudo apachectl -v 如下显示Apache的版本 sudo apachectl start 这 ...
- Git资料
git作为流行的分布式版本管理系统,虽然入门有点难,不过学会还是很有用的,尤其是针对技术人员.它从2005年Linux作者两周用C++写的一个版本发展到现在这么流行也是有原因的. Downloads ...
- [Java.web]MVC 案例-开发用户模块(注册)
代码下载 生成后的 user.xml 路径在 X:\day09_user\WebRoot\WEB-INF\classes\users.xml 使用测试 在 day09 项目上右键 -> Run ...
- Java缓存相关memcached、redis、guava、Spring Cache的使用
随笔分类 - Java缓存相关 主要记录memcached.redis.guava.Spring Cache的使用 第十二章 redis-cluster搭建(redis-3.2.5) 摘要: redi ...
- 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛-等式(求$N^2$的因子个数)
一.题目链接 https://www.nowcoder.com/acm/contest/90/F 二.题面 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言655 ...
- CFGym 101161I 题解
一.题目链接 http://codeforces.com/gym/101161/problem/I 二.题意 给定一棵树,一个初始的省会城市,若干个询问,0表示修改省会城市,1表示查询去省会必须经过指 ...
- 一.jQuery源码解析之总体架构
(function (window, undefined) { //构建jQuery对象 var document = window.document, navigator = window.navi ...
- python logging 重复写日志问题
用Python的logging模块记录日志时,遇到了重复记录日志的问题,第一条记录写一次,第二条记录写两次,第三条记录写三次...很头疼,这样记日志可不行.网上搜索到了原因与解决方案: 原因:没有移除 ...
- canvas绘制文本
canvas绘制文本 属性和方法 font = value 设置字体 textAlign = value 设置字体对齐方式 start, end, left, right, center textBa ...