牛牛的等差数列【线段树】
题目链接
这里的突破口在于小于等于25且大于等于3的质数连乘在1e8左右,所以,我们可以在操作上,将其看作对1e8去求模,而不是对每个都进行预处理。
时间复杂度。也就是说,我们排除这个预处理之后,直接就是降了10倍左右的复杂度。
然后,给区间一个等差数列,可以看成给这段区间赋一个基础值和递增一个值,所以我们在线段树上操作的时候,维护两个懒标记,分别是基础值,和等差值。因为存在累加(线性)关系,所以直接利用累加即可。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
//#include <unordered_map>
//#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define Big_INF 0x3f3f3f3f3f3f3f3f
#define eps 1e-8
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 2e5 + 7;
const ull mod[8] = {3, 5, 7, 11, 13, 17, 19, 23};
const ull MOD = 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23;
inline int _ID(ull mx) { return (int)(lower_bound(mod, mod + 8, mx) - mod); }
int N, Q;
ull a[maxN], tree[maxN << 2], sum[maxN << 2], del[maxN << 2];
bool lazy[maxN << 2] = {false};
inline void pushup(int rt) { tree[rt] = (tree[lsn] + tree[rsn]) % MOD; }
void buildTree(int rt, int l, int r)
{if(l == r) { tree[rt] = a[l] % MOD; return; }int mid = HalF;buildTree(Lson); buildTree(Rson);pushup(rt);
}
inline void pushdown(int rt, int l, int r)
{if(lazy[rt]){int mid = HalF; ull len_L = mid - l + 1, len_R = r - mid;lazy[lsn] = lazy[rsn] = true;sum[lsn] = (sum[lsn] + sum[rt]) % MOD;del[lsn] = (del[lsn] + del[rt]) % MOD;tree[lsn] = (tree[lsn] + sum[rt] * len_L + (len_L - 1LL) * len_L / 2LL % MOD * del[rt] % MOD) % MOD;sum[rsn] = (sum[rsn] + sum[rt] + del[rt] * len_L) % MOD;del[rsn] = (del[rsn] + del[rt]) % MOD;tree[rsn] = (tree[rsn] + (sum[rt] + del[rt] * len_L) % MOD * len_R + (len_R - 1LL) * len_R / 2LL % MOD * del[rt]) % MOD;sum[rt] = del[rt] = 0;lazy[rt] = false;}
}
void update(int rt, int l, int r, int ql, int qr, ull val, ull d)
{if(ql <= l && qr >= r){ull fir_v = (val + d * (l - ql)) % MOD;lazy[rt] = true;sum[rt] = (sum[rt] + fir_v) % MOD;del[rt] = (del[rt] + d) % MOD;tree[rt] = (tree[rt] + fir_v * (r - l + 1) % MOD + (ull)(r - l) * (r - l + 1) / 2LL * d) % MOD;return;}pushdown(myself);int mid = HalF;if(qr <= mid) update(QL, val, d);else if(ql > mid) update(QR, val, d);else { update(QL, val, d); update(QR, val, d); }pushup(rt);
}
ull query(int rt, int l, int r, int ql, int qr, int op)
{if(ql <= l && qr >= r) return tree[rt] % mod[op];pushdown(myself);int mid = HalF;if(qr <= mid) return query(QL, op);else if(ql > mid) return query(QR, op);else return (query(QL, op) + query(QR, op)) % mod[op];
}
int main()
{scanf("%d", &N);for(int i=1; i<=N; i++) scanf("%lld", &a[i]);buildTree(1, 1, N);scanf("%d", &Q); int op, l, r, v, d;while(Q--){scanf("%d", &op);if(op == 1){scanf("%d%d%d%d", &l, &r, &v, &d);update(1, 1, N, l, r, v, d);}else{scanf("%d%d%d", &l, &r, &d);printf("%lld\n", query(1, 1, N, l, r, _ID(d)));}}return 0;
}
牛牛的等差数列【线段树】相关推荐
- BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...
- 【线段树 集合hash】bzoj4373: 算术天才⑨与等差数列
hash大法好(@ARZhu):大数相乘及时取模真的是件麻烦事情 Description 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你, ...
- 舒老师AK的hu测 T2. LX还在迷路(线段树+等差数列)
版权属于舒老师,想要引用此题(包括题面)的朋友请联系博主 分析: 这道题是舒老师的原创题(版权声明~) 神题啊,毒瘤题啊 正解 首先,我们可以先忽略n(n+1)2n(n+1)2n(n+1) \over ...
- bzoj 1558: [JSOI2009]等差数列 (线段树)
题目描述 传送门 题目大意:给定一个长度为N的数列,初始时第i个数为vi. 操作(1)A s t a b在序列的[s,t]区间上加上初值为a,步长为b的等差数列.即vi变为vi+a+b*(i-s) 操 ...
- 牛客 - 牛牛的Link Power II(线段树)
题目链接:点击查看 题目大意:给出一个01字符串 s ,现在规定每两个 1 的贡献为其在字符串中的距离,现在有 m 次操作,每次操作会把一个位置将 0 变成 1 或者将 1 变成 0 ,问每次操作后字 ...
- 【牛客NOIP模拟】 牛牛的RPG游戏【二维偏序】【任意坐标斜率优化】【CDQ 分治】【李超线段树】
题意: n×mn\times mn×m 的网格图,每个点有两个权值 vali,j,bufi,jval_{i,j},buf_{i,j}vali,j,bufi,j,从 (1,1)(1,1)(1,1) ...
- szu 寒训个人复习第一天 线段树入门单点修改,区间修改,以及线段树的扩展运用[线段树+dp][区间最大公约数]
寒讯内容有点过多(其实是我太菜了)水一波怕忘了(人老了)**什么是线段树** 线段树是本蒟蒻感觉用处特别大的算法 那么线段树上面的节点表示什么意思呢? 线段树,上面的节点表示一个区间,父亲节点表示的区 ...
- 洛谷P2221 [HAOI2012]高速公路(线段树+概率期望)
传送门 首先,答案等于$$ans=\sum_{i=l}^r\sum_{j=i}^r\frac{sum(i,j)}{C_{r-l+1}^2}$$ 也就是说所有情况的和除以总的情况数 因为这是一条链,我们 ...
- 洛谷 - P4062 [Code+#1]Yazid 的新生舞会(推公式+线段树)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,现在要求存在 绝对众数 的子区间个数 所谓 绝对众数,就是对于区间 [l,r][l,r][l,r] 来说,存在一个数字的出现次数 cntc ...
- 中石油训练赛 - 小A盗墓(线段树+异或结论)
题目链接:点击查看 题目大意:给出n个数,以及m个操作,每个操作分为两种: 1 x y:将第x个数变为y 2 x y:判断闭区间[x,y]中的数能否在进行升序排序后构成一段连续且上升序列 题目分析:因 ...
最新文章
- linux 安装删除命令,Linux如何使用命令行卸载安装包
- java uml 为什么_Java开发为什么需要UML
- linux RTX2080显卡驱动
- bootstrap-dist的下载和使用bootstrap可视化布局代码无样式解决
- rdd转换成java数据结构_如何将CSV文件转换为RDD
- Windows server 2008 R2 个人使用修改==转载+原创
- 蓝桥杯2015年第六届C/C++省赛A组第七题-手链样式
- 两种方式打开jar文件
- spring boot设置项目名称
- 让 orangepi 用上Btsync(资源分享工具)好资源不怕和谐!
- win10系统升级后Auto CAD2008过期解决办法
- Window 错误代码大全
- 红外对管信号处理电路(滞回比较器)
- 选第二大算法(锦标赛算法)
- 关于Raft的一些问题解答
- 安卓 手柄 linux,Linux joystick 游戏手柄编程 (获取输入数据)
- leetcode第一题
- STM32 GPS悬停飞控 (三十五)树莓派 4g视频回传
- android壁纸和手机屏幕之间要怎么对应,android手机壁纸
- python 重复图片_删除重复文件或图片(去重)的python代码