BZOJ1798: [Ahoi2009]Seq 维护序列seq
来源:互联网 发布:史蒂芬库里 知乎 编辑:程序博客网 时间:2024/06/03 06:21
Description
老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。
Input
第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。
Output
对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。
Sample Input
7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7
Sample Output
2
35
8
HINT
【样例说明】
初始时数列为(1,2,3,4,5,6,7)。
经过第1次操作后,数列为(1,10,15,20,25,6,7)。
对第2次操作,和为10+15+20=45,模43的结果是2。
经过第3次操作后,数列为(1,10,24,29,34,15,16}
对第4次操作,和为1+10+24=35,模43的结果是35。
对第5次操作,和为29+34+15+16=94,模43的结果是8。
测试数据规模如下表所示
数据编号 1 2 3 4 5 6 7 8 9 10
N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
题目传送门
第一反应是莫队,看来我学数据结构都快学傻了…
O(100000^3/5)是2亿多,那待修莫队就肯定跑不过去
所以要用线段树的lazy标记
最大的坑点还是要注意乘法标记和加法标记的顺序
一定要先加后乘
winter is coming凛冬将至 ——《Game of Thrones》
代码如下:
#include<cmath>#include<cstdio>#include<cstring>#include<cstdlib> #include<algorithm>using namespace std;typedef long long ll;int n;ll mod;struct trnode{ int l,r,lc,rc; ll c,mul,add;}tr[1110000];int trlen;ll a[110000];void bt(int l,int r){ int now=++trlen; tr[now].l=l;tr[now].r=r;tr[now].c=0; tr[now].lc=tr[now].rc=-1; tr[now].mul=1,tr[now].add=0; if(l==r){tr[now].c=a[l]%mod;return ;} if(l<r){ int mid=(l+r)/2; tr[now].lc=trlen+1;bt(l,mid); tr[now].rc=trlen+1;bt(mid+1,r); } tr[now].c=tr[tr[now].lc].c+tr[tr[now].rc].c;}void lazy(int x){ int lc=tr[x].lc,rc=tr[x].rc; int l=tr[x].l,r=tr[x].r;int mid=(l+r)/2; if(lc!=-1){ tr[lc].c=(tr[lc].c*tr[x].mul)%mod; tr[lc].c=(tr[lc].c+tr[x].add*(mid-l+1))%mod; tr[lc].mul=(tr[lc].mul*tr[x].mul)%mod; tr[lc].add=(tr[lc].add*tr[x].mul)%mod; tr[lc].add=(tr[lc].add+tr[x].add)%mod; } if(rc!=-1){ tr[rc].c=(tr[rc].c*tr[x].mul)%mod; tr[rc].c=(tr[rc].c+tr[x].add*(r-mid))%mod; tr[rc].mul=(tr[rc].mul*tr[x].mul)%mod; tr[rc].add=(tr[rc].add*tr[x].mul)%mod; tr[rc].add=(tr[rc].add+tr[x].add)%mod; } tr[x].mul=1;tr[x].add=0;}void jia(int now,int l,int r,ll c){ if(l==tr[now].l&&tr[now].r==r){ tr[now].c=(tr[now].c+(r-l+1)*c)%mod; tr[now].add=(tr[now].add+c)%mod; return ; } int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; lazy(now); if(r<=mid)jia(lc,l,r,c); else if(mid+1<=l)jia(rc,l,r,c); else{ jia(lc,l,mid,c); jia(rc,mid+1,r,c); } tr[now].c=(tr[lc].c+tr[rc].c)%mod;}void cheng(int now,int l,int r,ll c){ if(l==tr[now].l&&r==tr[now].r){ tr[now].c=(tr[now].c*c)%mod; tr[now].add=(tr[now].add*c)%mod; tr[now].mul=(tr[now].mul*c)%mod; return ; } int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; lazy(now); if(r<=mid)cheng(lc,l,r,c); else if(mid+1<=l)cheng(rc,l,r,c); else{ cheng(lc,l,mid,c); cheng(rc,mid+1,r,c); } tr[now].c=(tr[lc].c+tr[rc].c)%mod;}ll findsum(int now,int l,int r){ if(l==tr[now].l&&r==tr[now].r){ lazy(now); return tr[now].c%mod; } int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; lazy(now); if(r<=mid)return findsum(lc,l,r); else if(mid+1<=l)findsum(rc,l,r); else return (findsum(lc,l,mid)%mod+findsum(rc,mid+1,r)%mod)%mod;}int main(){ scanf("%d%lld",&n,&mod); for(int i=1;i<=n;i++)scanf("%lld",&a[i]); trlen=0;bt(1,n); int m; scanf("%d",&m); while(m--){ int q,l,r; scanf("%d%d%d",&q,&l,&r); if(q==3){printf("%lld\n",findsum(1,l,r)%mod);continue;} ll c; scanf("%lld",&c); if(q==2)jia(1,l,r,c); else cheng(1,l,r,c); } return 0;}
by_lmy
- 【bzoj1798】[Ahoi2009]Seq 维护序列seq
- bzoj1798[Ahoi2009]Seq 维护序列seq
- [BZOJ1798][Ahoi2009]Seq 维护序列seq
- [BZOJ1798] [Ahoi2009]Seq 维护序列seq
- 【AHOI2009】【BZOJ1798】Seq 维护序列seq
- BZOJ1798 [Ahoi2009]Seq 维护序列seq
- bzoj1798: [Ahoi2009]Seq 维护序列seq
- 【follow】 BZOJ1798: [Ahoi2009]Seq 维护序列seq
- bzoj1798: [Ahoi2009]Seq 维护序列seq
- BZOJ1798: [Ahoi2009]Seq 维护序列seq
- BZOJ1798:[Ahoi2009]Seq 维护序列 线段树
- BZOJ1798 【AHOI2009】 seq维护序列 <线段树>
- 【BZOJ1798】[Ahoi2009]Seq 维护序列seq 线段树
- bzoj1798: [Ahoi2009]Seq 维护序列seq 线段树
- 【bzoj1798】[Ahoi2009]Seq 维护序列seq 线段树
- 【BZOJ1798】[Ahoi2009]Seq 维护序列seq 【线段树】
- BZOJ1798——[Ahoi2009]Seq维护序列seq
- [线段树] BZOJ1798: [Ahoi2009]Seq 维护序列seq
- studio 更新到3.0后报错问题及解决方案
- 2.判断是否是制单人
- 2012年系统架构师考试题详解
- TOP100summit:【分享实录-美团点评】 业务快速升级发展背后的系统架构演进
- 什么是跨域?怎么解决跨域问题?
- BZOJ1798: [Ahoi2009]Seq 维护序列seq
- 查询上周同天的指标数据(查小时表)
- UVA 10003
- 前端规范
- 数组变量
- SQL On Linux 初体验
- HBuilder 连接 安卓模拟器 调试
- Android 使用mediaplayer播放res/raw文件夹中的音乐的实例
- ctags使用详解