题目大意:维护一个 N 个数组成的序列,支持区间加、区间乘、单点询问。

题解:在每一个块中维护两个标记,即:整块加和的标记和整块乘积的标记。不过由于有两个标记,涉及到计算区间总和的顺序问题。

一个指定块的区间加标记为 \(atag\),区间乘标记为 \(mtag\),区间除去标记的和为 \(sum\)。

第一种方式:\((sum+atag)*mtag\),第二种方式:\(sum*mtag+atag\)。

比如:假设现在区间加标记要增加 \(val\),若采用第一种方式,需要保证 \(atag*mtag=add+val\),显然这需要使得 \(mtag\) 的值改变,因此并不合适。

相反,如果采用第二种方式的话,加法只会改变加法标记,而区间乘法标记改变时,只需将乘法标记同样乘在加法标记上即可,精度符合要求。

综上,可以理解为乘法标记的优先级更高,即:先做乘法运算,后做加法运算。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int mod=10007; inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
} int n,q,tot,pos[maxn];
long long a[maxn];
struct node{
int l,r;
long long mul,add;
}b[1000]; void make_block(){
tot=(int)sqrt(n);
for(int i=1;i<=tot;i++)b[i].l=(i-1)*tot+1,b[i].r=i*tot;
if(b[tot].r<n)++tot,b[tot].l=b[tot-1].r+1,b[tot].r=n;
for(int i=1;i<=tot;i++)
for(int j=b[i].l;j<=b[i].r;j++)
pos[j]=i,b[i].mul=1;
} void read_and_parse(){
n=read(),q=n;
for(int i=1;i<=n;i++)a[i]=read();
make_block();
} void reset(int x){
for(int i=b[x].l;i<=b[x].r;i++)a[i]=(a[i]*b[x].mul+b[x].add)%mod;
b[x].add=0,b[x].mul=1;
} void modify(int opt,int l,int r,int val){
int x=pos[l],y=pos[r];
if(x==y){
reset(x);
for(int i=l;i<=r;i++)opt?a[i]*=val:a[i]+=val,a[i]%=mod;
}else{
for(int i=x+1;i<=y-1;i++){
if(opt==0)b[i].add=(b[i].add+val)%mod;
else b[i].add=(b[i].add*val)%mod,b[i].mul=(b[i].mul*val)%mod;
}
reset(x),reset(y);
for(int i=l;i<=b[x].r;i++)opt?a[i]*=val:a[i]+=val,a[i]%=mod;
for(int i=b[y].l;i<=r;i++)opt?a[i]*=val:a[i]+=val,a[i]%=mod;
}
} void solve(){
int opt,l,r,val;
while(q--){
opt=read(),l=read(),r=read(),val=read();
if(opt==0)modify(opt,l,r,val);
else if(opt==1)modify(opt,l,r,val);
else printf("%lld\n",(a[r]*b[pos[r]].mul+b[pos[r]].add)%mod);
}
} int main(){
read_and_parse();
solve();
return 0;
}

【LOJ#6283】数列分块7的更多相关文章

  1. LOJ #6283. 数列分块入门 7-分块(区间乘法、区间加法、单点查询)

    #6283. 数列分块入门 7 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 2   题目描述 给出 ...

  2. LOJ#6283. 数列分块入门 7

    对于每个区间先乘在加,如果我修改的是部分的块,我就需要把现这个块的add和mul标记全部放下去,然后再更新. #include<map> #include<set> #incl ...

  3. LOJ——#6277. 数列分块入门 1

    ~~推荐播客~~ 「分块」数列分块入门1 – 9 by hzwer 浅谈基础根号算法——分块 博主蒟蒻,有缘人可直接观摩以上大佬的博客... #6277. 数列分块入门 1 题目大意: 给出一个长为 ...

  4. LOJ 6277-6280 数列分块入门 1-4

    数列分块是莫队分块的前置技能,练习一下 1.loj6277 给出一个长为n的数列,以及n个操作,操作涉及区间加法,单点查值. 直接分块+tag即可 #include <bits/stdc++.h ...

  5. LOJ #6285. 数列分块入门 9-分块(查询区间的最小众数)

    #6285. 数列分块入门 9 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 2   题目描述 给 ...

  6. LOJ #6284. 数列分块入门 8-分块(区间查询等于一个数c的元素,并将这个区间的所有元素改为c)

    #6284. 数列分块入门 8 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 2   题目描述 给出 ...

  7. LOJ #6282. 数列分块入门 6-分块(单点插入、单点查询、数据随机生成)

    #6282. 数列分块入门 6 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 1   题目描述 给出 ...

  8. LOJ #6281. 数列分块入门 5-分块(区间开方、区间求和)

    #6281. 数列分块入门 5 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 5   题目描述 给出 ...

  9. LOJ #6280. 数列分块入门 4-分块(区间加法、区间求和)

    #6280. 数列分块入门 4 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论   题目描述 给出一个 ...

  10. LOJ #6279. 数列分块入门 3-分块(区间加法、查询区间内小于某个值x的前驱(比其小的最大元素))

    #6279. 数列分块入门 3 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 3   题目描述 给 ...

随机推荐

  1. Ionic 3 延迟加载(Lazy Load)实战(一)

    本文分享并演示了在 Ionic 3 框架中如何进行模块的延迟加载(Lazy Load)开发. 在我的实战课程「快速上手Ionic3 多平台开发企业级问答社区」中,因为开发的仿知乎 App 模块间的加载 ...

  2. RetrieveFavicon 获取任何站点的 favicon

    原文发表于我的技术博客 开源了一个获取任何站点 favicon 的类库,供使用. 原文发表于我的技术博客 RetrieveFavicon Project GitHub Retrieve favicon ...

  3. 记录网件r6220路由器登录配置

    1.设置本地连接为自动获取ip和DNS地址 2.使用网线连接电脑和路由器的LAN口 3.http://routerlogin.net/BRS_index.htm 4.用户名和密码: admin pas ...

  4. 撰写POPUSH需求文档

    不当家不知柴米贵,撰写了正规的软件需求文档才知道软件工程的复杂性 感谢@洪宇@王需@江林楠下午的加班加点,五个人正闷在406B奋斗中,加油!

  5. 《Linux内核设计与实现》读书笔记 3

    第三章 进程管理 3.1进程 概念: 进程:处于执行期的程序.但不仅局限于程序,还包含其他资源(打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内催音社的内存地址空间及一个或多个执行线 ...

  6. HanderBar

    对于java开发,涉及到页面展示时,比较主流的有两种解决方案: 1. struts2+vo+el表达式. 这种方式,重点不在于struts2,而是vo和el表达式,其基本思想是:根据页面需要的信息,构 ...

  7. David Silver强化学习Lecture3:动态规划

    课件:Lecture 3: Planning by Dynamic Programming 视频:David Silver强化学习第3课 - 动态规划(中文字幕) 动态规划 动态(Dynamic): ...

  8. 关于js中this指向的理解总结!

    关于js中this指向的理解! this是什么?定义:this是包含它的函数作为方法被调用时所属的对象. 首先,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁 ...

  9. CentOS 使用SMB服务 让windows能够上传文件

    1. 新增加用户 useradd zhaobsh 2. 使用 pdbedit的方式新增加用户 pdbedit -a -u zhaobsh 3. 修改smb服务 systemctl restart sm ...

  10. SLAM中的变换(旋转与位移)表示方法

    1.旋转矩阵 注:旋转矩阵标题下涉及到的SLAM均不包含位移. 根据同一点P在不同坐标系下e(e1,e2,e3)e'(e1',e2',e3')的坐标a(a1,a2,a3)a'(a1',a2',a3') ...