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以内的任何数都 ...
随机推荐
- python学习(二)—简明python教程
2016-04-14 20:55:16 八.模块 简介 前面介绍了如何在程序中定义一次函数而重用代码.在其他程序中重用很多函数,就需要使用模块.模块基本上就是一个包含了所有你定义的函数和变量的文件.模 ...
- win10 下ie11安装flash debuger (install flashplayer debuger on win10 64bit)
1不能安装的现象 由于win10 ie11 内置flash 微软不让用户自己手动更新ie11的flash以及安装flash debugger ,这怕是让还在用 flex 开发的大胸弟们很头疼 ...
- jmap打dump异常
背景 用jmap打dump文件经常遇到如下异常,打不出来,哥今天告拆大家一个终极解决方法,嘘,不要告拆别人.. Attaching to core -F from executable 421442, ...
- 在linux下利用nohup来后台运行java程序
nohup java -jar /etc/deny/denyHttp_fat.jar & http://limaoyuan.iteye.com/blog/900928 http://zshou ...
- 黄聪:Wordpress程序Mysql查询导致CPU100%,页面错误增量飙高解决方案
最近做的网站,访客一多,CPU就会飙到100%,找了网上很多解决方案,用了下面的方法进行优化: 1.mysql开启慢查询方法: 在my.ini的[mysqld]添加如下语句: log-slow-que ...
- Go语言面组合式向对象编程基础总结
转自:http://blog.csdn.net/yue7603835/article/details/44282823 Go语言的面向对象编程简单而干净,通过非侵入式接口模型,否定了C/C++ Jav ...
- 管理Linux服务器的用户和组(续篇)
用户切换 新建用户 useradd命令的选项 设置用户口令 passwd命令的选项 chage命令 修改用户帐户 禁用和恢复用户帐户 禁用和恢复用户帐户- Passwd命令 禁用和恢复用户帐户-直接修 ...
- linux-修改pip源
1.进入家目录的隐藏 .pip目录下 cd ~/.pip 2.创建并修改pip.conf [global]timeout = 10 # 超时 index-url = http://mirrors.a ...
- Linux测试环境搭建apache+mysql+php
Linux Red Hat Enterprise Linux Server release 5.4 (Tikanga) Kernel \r on an \m Apache +Mysql+php 搭建准 ...
- Python处理文本换行符
源文件每行后面都有回车,所以用下面输出时,中间会多了一行 try: with open("F:\\hjt.txt" ) as f : for line in f: print(li ...