题目描述

At the children's day, the child came to Picks's house, and messed his house up. Picks was angry at him. A lot of important things were lost, in particular the favorite sequence of Picks.

Fortunately, Picks remembers how to repair the sequence. Initially he should create an integer array \(a[1],a[2],...,a[n]\). Then he should perform a sequence of \(m\) operations. An operation can be one of the following:

  1. Print operation \(l,r\). Picks should write down the value of \(\sum_{i=1}^{r} a[i]\).

  2. Modulo operation \(l,r,x\). Picks should perform assignment \(a[i]=a[i]\) \(\%\) \(x\) for each \(i\) \((l<=i<=r)\).

  3. Set operation \(k,x\). Picks should set the value of \(a[k]\) to \(x\) (in other words perform an assignment \(a[k]=x\)).

Can you help Picks to perform the whole sequence of operations?

输入输出格式

输入格式

The first line of input contains two integer: \(n,m\) \((1<=n,m<=10^{5})\). The second line contains \(n\) integers, separated by space: \(a[1],a[2],...,a[n] (1<=a[i]<=10^{9})\) — initial value of array elements.

Each of the next m m m lines begins with a number type type type .

  • If \(type=1\), there will be two integers more in the line: \(l,r (1<=l<=r<=n)\) , which correspond the operation \(1\).

  • If \(type=2\), there will be three integers more in the line: \(l,r,x (1<=l<=r<=n; 1<=x<=10^{9})\) , which correspond the operation \(2\).

  • If \(type=3\), there will be two integers more in the line: \(k,x (1<=k<=n; 1<=x<=10^{9})\) , which correspond the operation \(3\).

输出格式

For each operation \(1\), please print a line containing the answer. Notice that the answer may exceed the 32-bit integer.

输入输出样例

输入样例#1

5 5
1 2 3 4 5
2 3 5 4
3 3 5
1 2 5
2 1 3 3
1 1 3

输出样例#1

8
5

输入样例#2

10 10
6 9 6 7 6 1 10 10 9 5
1 3 9
2 7 10 9
2 5 10 8
1 4 7
3 3 7
2 7 9 9
1 2 4
1 6 6
1 5 9
3 1 10

输出样例#2

49
15
23
1
9

说明

Consider the first testcase:

  • At first, \(a={1,2,3,4,5}\).

  • After operation \(1\), \(a={1,2,3,0,1}\).

  • After operation \(2\), \(a={1,2,5,0,1}\).

  • At operation \(3\), \(2+5+0+1=8\).

  • After operation \(4\), \(a={1,2,2,0,1}\).

  • At operation \(5\), \(1+2+2=5\).

题意翻译

给定数列,区间查询和,区间取模,单点修改。

\(n,m\)小于\(10^5\)

题解

线段树基础题。

区间查询和、单点修改很简单,也很基础,这里就不在赘述。

重点来看一下区间取模。

首先,我们不难知道,当一个数\(a \% b\)时,如果\(a < b\),那么这个取模是没有什么意义的(\(*\))。

如果,我们执行区间取模时,一个一个数去取模,那么复杂度会非常高,达到\(\Theta (n \times m)\),绝对会\(TLE\)。

因此考虑一种类似搜索“剪枝”的方式来优化区间取模。

这时,我们就要用到上面的(\(*\))了。

用一个数组\(mx[]\)来记录区间内的最大值,如果这个最大值都小于我们要取模的那个数了,就直接\(return\)返回掉,因为对这个区间取模就已经没有意义了。

很容易就可以写出\(AC\)代码。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#define int long long using namespace std; inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar();}
return f * x;
} int n/*数的个数*/, m/*操作个数*/, tr[100003 << 2]/*区间和*/, mx[100003 << 2]/*区间最大值*/, a[100003]/*每个数的值*/; inline void pushup(int p)//上传节点操作
{
mx[p] = max(mx[p << 1], mx[(p << 1) | 1]);//更新区间最大值
tr[p] = tr[p << 1] + tr[(p << 1) | 1];//加上区间和
} void build(int s, int t, int p)//建树操作
{
if (s == t)//已经是叶子节点了
{
mx[p] = tr[p] = a[s];//更新节点的参数
return;//返回
}
int mid = (s + t) >> 1;//计算中间值
build(s, mid, p << 1); //递归左子树
build(mid + 1, t, (p << 1) | 1);//递归右子树
pushup(p);//上传当前节点
} void modify(int l/*要修改的数的编号,即目标节点*/, int r/*要更新的值*/, int s, int t, int p)//单点修改操作
{
if (s == t)//已经到了目标节点
{
mx[p] = tr[p] = r; //更新节点参数
return;//直接返回
}
int mid = (s + t) >> 1;//计算中间值
if (l <= mid) //目标节点在左区间
modify(l, r, s, mid, p << 1);//递归左子树寻找
else //目标节点在右区间
modify(l, r, mid + 1, t, (p << 1) | 1);//递归右区间查找
pushup(p);//上传当前节点
} void getmod(int l/*区间左界*/, int r/*区间右界*/, int mod/*要取模的值*/, int s, int t, int p)//区间取模操作
{
if (mx[p] < mod) return;//"剪枝"操作
if (s == t)//已经到了叶子节点
{
tr[p] = tr[p] % mod; //取模
mx[p] = tr[p];//更新最大值
return;//返回
}
int mid = (s + t) >> 1;//计算中间值
if (l <= mid) getmod(l, r, mod, s, mid, p << 1);//查找中点左边的区间进行取模
if (r > mid) getmod(l, r, mod, mid + 1, t, (p << 1) | 1);//查找中点右边的区间进行取模
pushup(p);//上传当前节点
} int getans(int l, int r, int s, int t, int p)//查询区间和操作
{
if (l <= s && t <= r) return tr[p];//当前区间完全包含于目标区间,就直接返回当前区间的和
int mid = (s + t) >> 1, ans = 0;//计算中间值及初始化答案
if (l <= mid) ans = ans + getans(l, r, s, mid, p << 1);//加上中点左边的区间进行求和
if (r > mid) ans = ans + getans(l, r, mid + 1, t, (p << 1) | 1);//加上中点右边的区间进行求和
return ans;//返回答案
} signed main()
{
n = gi(), m = gi();
for (int i = 1; i <= n; i++) a[i] = gi();
//以上为输入
build(1, n, 1);//建树
while (m--)
{
int fl = gi(), x = gi(), y = gi();
if (fl == 1)//是输出区间和操作
{
printf("%lld\n", getans(x, y, 1, n, 1));//就输出区间和
}
else if (fl == 2)//区间取模操作
{
int md = gi();//输入模数
getmod(x, y, md, 1, n, 1);//进行取模
}
else
{
modify(x, y, 1, n, 1);//否则就进行单点修改,注意是把点x的值修改为y
}
}
return 0;//结束
}

题解【Codeforces438D】The Child and Sequence的更多相关文章

  1. 题解——CodeForces 438D The Child and Sequence

    题面 D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input ...

  2. Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间取摸

    D. The Child and Sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest ...

  3. Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间求和+点修改+区间取模

    D. The Child and Sequence   At the children's day, the child came to Picks's house, and messed his h ...

  4. Codeforce 438D-The Child and Sequence 分类: Brush Mode 2014-10-06 20:20 102人阅读 评论(0) 收藏

    D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input st ...

  5. Codeforces Round #250 (Div. 1) D. The Child and Sequence(线段树)

    D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input st ...

  6. Codeforces Round #250 (Div. 1) D. The Child and Sequence

    D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input st ...

  7. AC日记——The Child and Sequence codeforces 250D

    D - The Child and Sequence 思路: 因为有区间取模操作所以没法用标记下传: 我们发现,当一个数小于要取模的值时就可以放弃: 凭借这个来减少更新线段树的次数: 来,上代码: # ...

  8. 438D - The Child and Sequence

    D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input st ...

  9. Codeforces 438D The Child and Sequence - 线段树

    At the children's day, the child came to Picks's house, and messed his house up. Picks was angry at ...

随机推荐

  1. 剑指offer-面试题23-链表中环的入口节点-双指针

    /* 题目: 如果链表中包含环,如何找出环的入口? */ /* 思路: 双指针: 1.判断是否有环. fast指针一次2步,slow指针一次1步,当fast与slow相遇时,说明有环. 2.判断环路中 ...

  2. LTC

    LTC 即 L2C,Leads To Cash,从线索到现金的企业运营管理思想,是以企业的营销和研发两大运营核心为主线,贯穿企业运营全部流程,深度融合了移动互联.SaaS技术.大数据与企业运营智慧,旨 ...

  3. cin,cin.get(),cin.getline(),gets(),getchar()函数的用法

    1.cin>> 用法a:最基本的流输入用法,接受一个数字或字符,自动跳过输入的空格. 用法b:接受一个字符串,但是遇到除开头外的空格则会终止输入. #include<iostream ...

  4. js数据类型1

    1. 分类(2大类) 基本(值)类型--5种 Number: 任意数值 String: 任意文本 Boolean: true/false undefined: undefined null: null ...

  5. Oracle 12c 如何在 PDB 中添加 SCOTT 模式(数据泵方式)

    Oracle 12c 建库后,没有 scott 模式,本篇使用数据泵方式,在12c版本之前数据库中 expdp 导出 scott 模式,并连接 12c 的 pdb 进行 impdp 导入. 目录 1. ...

  6. 折半枚举+Hash(HDU1496升级版)

    题目链接:N - 方程的解 给定一个四元二次方程: Ax1^2+Bx2^2+Cx3^2+Dx4^2=0 试求−1000≤x1,x2,x3,x4≤1000非零整数解的个数. −10000≤A,B,C,D ...

  7. Linux的常用命令---这是对Linux最基本的尊重

    Linux: 诞生日期:1991年 开发者:林纳斯·托瓦茨 特点:免费,开源 发行版本:centos|red Hat|Ubuntu|红旗等 思想:一切都是文件 重要文件目录 bin:二进制文件(命令) ...

  8. 解决并发问题的CAS思想及原理

      全称为:Compare and swap(比较与交换),用来解决多线程并发情况下使用锁造成性能开销的一种机制:   原理思想:CAS(V,A,B),V为内存地址,A为预期原值,B为新值.如果内存地 ...

  9. 论文阅读笔记(四)【TIP2017】:Video-Based Pedestrian Re-Identification by Adaptive Spatio-Temporal Appearance Model

    Introduction (1)背景知识: ① 人脸识别是具有高可靠性的生物识别技术,但在低解析度(resolution)和姿态变化下效果很差. ② 步态(gait)是全身行为的生物识别特征,大部分步 ...

  10. C#关于文件的创建

    若使用文件夹Directory类判断了文件夹的存在,后面的文件就不需要使用File类来判断文件的存在与否和创建,只需要在前面判断过得文件夹路径后面加上文件的名字即可,它会自动判断文件是否存在,若不存在 ...