Codeforces 438D The Child and Sequence

给出一个序列,进行如下三种操作:

  1. 区间求和
  2. 区间每个数模x
  3. 单点修改

如果没有第二个操作的话,就是一棵简单的线段树。那么如何处理这个第二个操作呢?

对于一个数a,如果模数 x > a ,则这次取模是没有意义的,直接跳过;

如果 x > a/2 ,则取模结果小于 a / 2; 如果 x < a / 2,取模结果小于x,则也小于 a / 2。

所以对于一个数,最多只会做log a次取模操作。这是可以接受的!

对于一个区间,维护最大值,如果模数x > 最大值,直接跳过即可。

否则继续往下像单点修改一样。

时间复杂度不会超过 \(O(n \log ^2 n)\) ……吧。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define space putchar(' ')
#define enter putchar('\n')
template <class T>
bool read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
else if(c == EOF) return 0;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
return 1;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
} const int N = 100005;
int n, m, a[N], ma[4*N];
ll sum[4*N]; void build(int k, int l, int r){
if(l == r) return (void) (ma[k] = sum[k] = a[l]);
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
ma[k] = max(ma[k << 1], ma[k << 1 | 1]);
sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
void change(int k, int l, int r, int p, int x){
if(l == r) return (void) (ma[k] = sum[k] = x);
int mid = (l + r) >> 1;
if(p <= mid) change(k << 1, l, mid, p, x);
else change(k << 1 | 1, mid + 1, r, p, x);
ma[k] = max(ma[k << 1], ma[k << 1 | 1]);
sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
void mo(int k, int l, int r, int ql, int qr, int x){
if(ma[k] < x) return;
if(l == r) return (void) (ma[k] %= x, sum[k] %= x);
int mid = (l + r) >> 1;
if(ql <= mid) mo(k << 1, l, mid, ql, qr, x);
if(qr > mid) mo(k << 1 | 1, mid + 1, r, ql, qr, x);
ma[k] = max(ma[k << 1], ma[k << 1 | 1]);
sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
ll query(int k, int l, int r, int ql, int qr){
if(ql <= l && qr >= r) return sum[k];
int mid = (l + r) >> 1;
ll ret = 0;
if(ql <= mid) ret += query(k << 1, l, mid, ql, qr);
if(qr > mid) ret += query(k << 1 | 1, mid + 1, r, ql, qr);
return ret;
} int main(){
read(n), read(m);
for(int i = 1; i <= n; i++) read(a[i]);
build(1, 1, n);
int op, l, r, x;
for(int i = 1; i <= m; i++){
read(op);
if(op == 1){
read(l), read(r);
write(query(1, 1, n, l, r)), enter;
}
else if(op == 2){
read(l), read(r), read(x);
mo(1, 1, n, l, r, x);
}
else{
read(l), read(x);
change(1, 1, n, l, x);
}
}
return 0;
}

Codeforces 438D (今日gg模拟第二题) | 线段树 考察时间复杂度的计算 -_-|||的更多相关文章

  1. 51nod 1563 坐标轴上的最大团(今日gg模拟第一题) | 线段覆盖 贪心 思维题

    51nod 1563 坐标轴上的最大团 坐标轴上有n个点,每个点有一个权值.第i个点的坐标是 xi ,权值是 wi .现在对这些点建图.对于点对 (i,j) ,如果 |xi−xj|≥wi+wj ,那么 ...

  2. 2018.07.23 codeforces 438D. The Child and Sequence(线段树)

    传送门 线段树维护区间取模,单点修改,区间求和. 这题老套路了,对一个数来说,每次取模至少让它减少一半,这样每次单点修改对时间复杂度的贡献就是一个log" role="presen ...

  3. 【bzoj3638】Cf172 k-Maximum Subsequence Sum 模拟费用流+线段树区间合并

    题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...

  4. 「CQOI2006」简单题 线段树

    「CQOI2006」简单题 线段树 水.区间修改,单点查询.用线段树维护区间\([L,R]\)内的所有\(1\)的个数,懒标记表示为当前区间是否需要反转(相对于区间当前状态),下方标记时懒标记取反即可 ...

  5. hdu 5475 模拟计算器乘除 (2015上海网赛H题 线段树)

    给出有多少次操作 和MOD 初始值为1 操作1 y 表示乘上y操作2 y 表示除以第 y次操作乘的那个数 线段树的叶子结点i 表示 第i次操作乘的数 将1替换成y遇到操作2 就把第i个结点的值 替换成 ...

  6. MAZE(2019年牛客多校第二场E题+线段树+矩阵乘法)

    题目链接 传送门 题意 在一张\(n\times m\)的矩阵里面,你每次可以往左右和下三个方向移动(不能回到上一次所在的格子),\(1\)表示这个位置是墙,\(0\)为空地. 现在有\(q\)次操作 ...

  7. Codeforces 1368H - Breadboard Capacity(最小割+线段树维护矩阵乘法)

    Easy version:Codeforces 题面传送门 & 洛谷题面传送门 Hard version:Codeforces 题面传送门 & 洛谷题面传送门 首先看到这种从某一种颜色 ...

  8. codeforces 876 D. Sorting the Coins(线段树(不用线段树写也行线段树写比较装逼))

    题目链接:http://codeforces.com/contest/876/problem/D 题解:一道简单的类似模拟的题目.其实就是看右边连出来有多少连续不需要换的假设位置为pos只要找pos- ...

  9. Codeforces 407E - k-d-sequence(单调栈+扫描线+线段树)

    Codeforces 题面传送门 & 洛谷题面传送门 深感自己线段树学得不扎实-- 首先特判掉 \(d=0\) 的情况,显然这种情况下满足条件的区间 \([l,r]\) 中的数必须相同,双针扫 ...

随机推荐

  1. Table 组件构建过程中遇到的问题与解决思路

    在 GearCase 开源项目构建 Table 组件的过程中.遇到了各式各样的问题,最后尝试了各种方法去解决这些问题. 遇到的部分问题 checkbox 的全选和半选问题 table 组件的排序请求方 ...

  2. Netty源码分析第5章(ByteBuf)---->第6节: 命中缓存的分配

    Netty源码分析第6章: ByteBuf 第六节: 命中缓存的分配 上一小节简单分析了directArena内存分配大概流程, 知道其先命中缓存, 如果命中不到, 则区分配一款连续内存, 这一小节带 ...

  3. Maven ResourceBundle.getBundle读取Properties异常MissingResourceException: Can't find bundlei解决方法

    参考:https://blog.csdn.net/thousa_ho/article/details/72817616 问题描述 ResourceBundle读取properties配置文件提示 Mi ...

  4. [Windows][C#][.NET][WPF]基于ArcFace2.0+红外双目摄像头的活体检测

    废话不多说 直接上图这个是demo中用到的双目摄像头,一个是红外的,一个是正常的rgb摄像头两个usb接口,在电脑上呈现两路摄像头通道程序检测RGB输出图像,当检测到有人脸时,用RGB人脸的位置到红外 ...

  5. c++ getline()和get()的区别

    1.方法get(char &)和get(void)提供不跳过空白的单字符输入功能:2.函数get(char * , int , char)和getline(char * , int , cha ...

  6. Hyperledger Fabic中的Transaction流程

    Hyperledger Fabic中的Transaction流程 Transaction处理流程时从client发起proposal到背书节点,背书节点发返回背书结果.client再将proposal ...

  7. [ c++] cmake 编译时 undefined reference to `std::cout' 错误的解决方案

    cmake ..  和 make 之后,出现如下错误 Linking CXX executable ../../../bin/ModuleTest CMakeFiles/ModuleTest.dir/ ...

  8. Fourteenth scrum meeting

    闫昊 今日完成:整理上一阶段代码,规划第二阶段实施过程 明日完成:学习讨论区开发 唐彬 今日完成:整理上一阶段代码,规划第二阶段实施过程 明日完成:学习学习进度部分开发 史烨轩 今日完成:整理上一阶段 ...

  9. YQCB冲刺第二周第二天

    今天的任务依然为实现查看消费明细的功能. 遇到的问题为从数据库中分类读取,实现图标的显示. 站立会议为: 任务面板为:

  10. 四则运算2及PSP0设计项目计划

    时间比较紧,我简单写写我的设计思路: 题目在四则运算1的基础上控制产生题目的数量,这个可以用变量控制:打印方式也可选用变量控制,程序的关键是括号的生成.我们可以将整个四则运算式看成()+()的模型,然 ...