BZOJ 1798 [Ahoi2009]Seq 维护序列——线段树
来源:互联网 发布:numpy攻略 源码 编辑:程序博客网 时间:2024/04/30 05:37
1798: [Ahoi2009]Seq 维护序列seq
题目描述
老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。
输入
第一行两个整数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)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。
输出
对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。
解题思路
这题是很裸的线段树的题目,就是又有加又有乘,于是线段树就有了两个tag,传tag的时候稍微推一下。这道题我A了很久,半个月左右QAQ,最主要线段树没理解好,记住:传到x点tag的同时修正x点。嗯,这个很重要。
#include<cstdio>#define LL long longusing namespace std;const int maxn=100005;struct jz{ int L,R; LL tag1,tag2,w;}a[4*maxn];inline int _read(){ int num=0;char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') num=num*10+ch-48,ch=getchar(); return num;}int tt,n,m,w[maxn];void build(int x,int L,int R){ a[x].L=L;a[x].R=R;a[x].tag1=1; if (L==R){a[x].w=(LL)w[L]%tt;return;} int mid=L+R>>1; build(x*2,L,mid);build(x*2+1,mid+1,R); a[x].w=(a[x*2].w+a[x*2+1].w)%tt;}void Pushdown(int x){ if (a[x].L==a[x].R) return; int tag1=a[x].tag1,tag2=a[x].tag2;a[x].tag1=1;a[x].tag2=0; a[x*2].w=(a[x*2].w*tag1+(LL)tag2*(a[x*2].R-a[x*2].L+1))%tt; a[x*2+1].w=(a[x*2+1].w*tag1+(LL)tag2*(a[x*2+1].R-a[x*2+1].L+1))%tt; a[x*2].tag1=(a[x*2].tag1*tag1)%tt; a[x*2+1].tag1=(a[x*2+1].tag1*tag1)%tt; a[x*2].tag2=(a[x*2].tag2*tag1+tag2)%tt; a[x*2+1].tag2=(a[x*2+1].tag2*tag1+tag2)%tt;}void change(int x,int L,int R,int c,int p){ if (a[x].L==L&&a[x].R==R){ a[x].tag1=(a[x].tag1*c)%tt; a[x].tag2=(a[x].tag2*c+p)%tt; a[x].w=(a[x].w*c+(a[x].R-a[x].L+1)*p)%tt; return; } Pushdown(x); int mid=a[x].L+a[x].R>>1; if (R<=mid) change(x*2,L,R,c,p); else if (L>mid) change(x*2+1,L,R,c,p); else{change(x*2,L,mid,c,p);change(x*2+1,mid+1,R,c,p);} a[x].w=(a[x*2].w+a[x*2+1].w)%tt;}int query(int x,int L,int R){ if (a[x].L==L&&a[x].R==R) return a[x].w; Pushdown(x); int mid=a[x].L+a[x].R>>1; if (R<=mid) return query(x*2,L,R); else if (L>mid) return query(x*2+1,L,R); else return (query(x*2,L,mid)+query(x*2+1,mid+1,R))%tt;}int main(){ freopen("exam.in","r",stdin); freopen("exam.out","w",stdout); n=_read();tt=_read(); for (int i=1;i<=n;i++) w[i]=_read(); build(1,1,n); m=_read(); while (m--){ int t=_read(),x=_read(),y=_read(),z; if (t==1){z=_read();change(1,x,y,z,0);} if (t==2){z=_read();change(1,x,y,1,z);} if (t==3) printf("%d\n",query(1,x,y)); } return 0;}
1 0
- BZOJ 1798 [Ahoi2009]Seq 维护序列——线段树
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq|线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq (线段树)
- bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树)
- 【BZOJ】1798 [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq 线段树题解
- BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树模板
- bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ 1798 AHOI2009 Seq 维护序列 线段树
- BZOJ 1798 [Ahoi2009]维护序列seq (线段树)
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq
- bzoj 1798: [Ahoi2009]Seq 维护序列seq
- 【BZOJ 1798】 [Ahoi2009]Seq 维护序列seq
- bzoj 1798 [Ahoi2009]Seq 维护序列seq
- 【BZOJ 1798】[Ahoi2009]Seq 维护序列seq
- [BZOJ 1798][Ahoi2009]Seq 维护序列seq
- Island Perimeter
- 用关键字new创建对象 new都做了什么(随笔)
- ElasticSearch集群搭建
- L1-019. 谁先倒--Java-pat-天梯赛
- oracle创建用户 赋权
- BZOJ 1798 [Ahoi2009]Seq 维护序列——线段树
- jquery获取与设置元素的宽度与高度
- robotframework 使用自己的python库
- poj 1050 To the Max(DP)做法很多
- android studio生成签名导打包的方法
- Zurmo(十一)Relation之static::OWNED和NOOWNED
- struts2 简介及使用步骤
- iOS-OC-基本控件之UIPageControl
- 从源码解析LinkedList集合