线段树

  属于线段树中级应用吧……

  要打两种标记:乘法和加法标记。一开始我想着可以像只有加法标记那样,永不下传,查询的时候依次累加就好了。后来发现不会写……只好每次update的时候……遇到标记!下传!query的时候遇到标记!下传!暴力地来搞……

  然后说下下传的细节:先传乘法,后传加法。因为传乘法标记的时候要连sum带add都要一起乘,如果先传add就会多乘……

 /**************************************************************
Problem: 1798
User: Tunix
Language: C++
Result: Accepted
Time:3868 ms
Memory:6748 kb
****************************************************************/ //BZOJ 1798
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
//using namespace std;
const int N=;
typedef long long LL;
//#define debug
int n,m,P,a[N];
int mul[N<<],add[N<<],sum[N<<]; void read(int &v){
v=; int sign=; char ch=getchar();
while(ch<'' || ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>='' && ch<=''){ v=v*+ch-''; ch=getchar();}
v*=sign;
}
#define mid (l+r>>1)
#define L (o<<1)
#define R (o<<1|1) void Push_down(int o,int l,int r){
if (mul[o]!=){
add[L]=((LL)add[L]*mul[o])%P; add[R]=((LL)add[R]*mul[o])%P;
mul[L]=((LL)mul[L]*mul[o])%P; mul[R]=((LL)mul[R]*mul[o])%P;
mul[o]=;
}
if (add[o]!=){
add[L]=((LL)add[L]+add[o])%P; add[R]=((LL)add[R]+add[o])%P;
add[o]=;
}
}
void Push_up(int o,int l,int r){
if (l<r) sum[o]=(sum[L]+sum[R])%P; else sum[o]=;
sum[o]=((LL)sum[o]*mul[o]+(LL)add[o]*(r-l+))%P;
}
void build(int o,int l,int r){
if (l==r) add[o]=sum[o]=a[l],mul[o]=;
else{
build(L,l,mid);
build(R,mid+,r);
add[o]=; mul[o]=;
Push_up(o,l,r);
}
}
int ql,qr;
void update_add(int o,int l,int r,int v){
if (ql<=l && qr>=r)
add[o]=((LL)add[o]+v)%P;
else{
if (mul[o]!= || add[o]) Push_down(o,l,r);
if (ql<=mid) update_add(L,l,mid,v); else Push_up(L,l,mid);
if (qr>mid) update_add(R,mid+,r,v); else Push_up(R,mid+,r);
}
Push_up(o,l,r);
}
void update_mul(int o,int l,int r,int v){
if (ql<=l && qr>=r)
mul[o]=((LL)mul[o]*v)%P,add[o]=(LL)add[o]*v%P;
else{
if (mul[o]!= || add[o]) Push_down(o,l,r);
if (ql<=mid) update_mul(L,l,mid,v); else Push_up(L,l,mid);
if (qr>mid) update_mul(R,mid+,r,v); else Push_up(R,mid+,r);
}
Push_up(o,l,r);
}
int sumv;
void query(int o,int l,int r){
if (ql<=l && qr>=r)
sumv=((LL)sumv+sum[o])%P;
else{
if (mul[o]!= || add[o]) {Push_down(o,l,r); Push_up(L,l,mid); Push_up(R,mid+,r);}
if (ql<=mid) query(L,l,mid);
if (qr>mid) query(R,mid+,r);
}
}
int ans[N],cnt=;
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
read(n); read(P);
F(i,,n) read(a[i]);
// F(i,1,n) printf("%d ",a[i]);
// printf("\n");
build(,,n); read(m);
// printf("m=%d\n",m);
int c,v;
F(i,,m){
read(c); read(ql); read(qr);
// printf("c=%d\n",c);
switch(c){
case : read(v); update_mul(,,n,v); break;
case : read(v); update_add(,,n,v); break;
case : sumv=; query(,,n); ans[cnt++]=sumv;break;
}
}
rep(i,cnt-) printf("%d\n",ans[i]);
printf("%d",ans[cnt-]);
return ;
}

【BZOJ】【1798】【AHOI2009】Seq维护序列的更多相关文章

  1. BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )

    线段树.. 打个 mul , add 的标记就好了.. 这个速度好像还挺快的...( 相比我其他代码 = = ) 好像是#35.. ---------------------------------- ...

  2. bzoj 1798: [Ahoi2009]Seq 维护序列seq (线段树 ,多重标记下放)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 7773  Solved: 2792[Submit ...

  3. bzoj 1798: [Ahoi2009]Seq 维护序列seq 线段树 区间乘法区间加法 区间求和

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...

  4. Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...

  5. bzoj 1798 [Ahoi2009]Seq 维护序列seq(线段树+传标)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1798 [题意] 给定一个序列,要求提供区间乘/加,以及区间求和的操作 [思路] 线段树 ...

  6. BZOJ 1798 AHOI2009 Seq 维护序列 线段树

    题目大意:维护一个序列,提供三种操作: 1.将区间中每个点的权值乘上一个数 2.将区间中每个点的权值加上一个数 3.求一段区间的和对p取模的值 2631的超^n级弱化版.写2631之前能够拿这个练练手 ...

  7. bzoj 1798 [Ahoi2009]Seq 维护序列seq

    原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 线段树区间更新: 1. 区间同同时加上一个数 2. 区间同时乘以一个数 #inclu ...

  8. bzoj 1798 [Ahoi2009]Seq 维护序列seq ——线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1798 先乘后加,就可给加法标记乘上乘法标记. 注意可能有 *0 的操作,所以 pshd 时不 ...

  9. BZOJ 1798: [Ahoi2009]Seq 维护序列seq (线段树乘法加法的混合操作)

     题目:点击打开链接 大意:一个数组.三个操作.第一种是区间[a,b]每一个数乘乘,另外一种是区间[a,b]每一个数加c,第三种是查询[a,b]区间的和并对p取摸. 两种操作就不能简单的仅仅往下传 ...

  10. 1798: [Ahoi2009]Seq 维护序列seq

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 2930  Solved: 1087[Submit ...

随机推荐

  1. C# 执行JS

    需引用命名空间:Microsoft.VsaMicrosoft.JScript using System; using System.Collections.Generic; using System. ...

  2. 5.21_启程日本二面_1 vs 1

    昨天上午刚群面完,晚上7点左右就接到了电话.面试官就两位菇凉,看来她们也是很辛苦.今天下午3点 1 vs 1,在一家咖啡店里,主要是询问下去日本的意愿是否足够强烈.太老实,这里实话实说,也没有表现出非 ...

  3. mysql之数据库基本概念(mysql学习笔记一)

    数据库系统   数据库管理系统(DBMS)+数据库(DATABASE)(+数据库管理员) DBS=dbms+db 定义: 大量信息进行管理的高效解决方案,按照数据结构来组织.存储和管理数据的仓库 关系 ...

  4. 转:浅谈关于b、h标签的优化技巧

    <b>标签优化 <b>标签是一种加粗标记,作用就是加粗文章中的关键词,对于文章中重要的关键词加粗起到有利于用户阅读的作用.<b>标签的使用对于优化的作用是非常大的, ...

  5. wordpress学习-themes-001

    这一篇主要是来记录wordpress theme的内容.关于为什么要自己编写wordpress theme的理由,相信大家都有各自的体会.想让自己的博客变的更加突出?更加个性话?wordpress t ...

  6. C# 截取带路径的文件名字,扩展名,等等 的几种方法

    C#对磁盘IO操作的时候,经常会用到这些,路径,文件,文件名字,文件扩展名. 之前,经常用切割字符串来实现, 可是经常会弄错. 尤其是启始位置,多少个字节,经常弄晕. 下面这种方法貌似比较简便: st ...

  7. python中读取配置文件ConfigParser

    在程序中使用配置文件来灵活的配置一些参数是一件很常见的事情,配置文件的解析并不复杂,在python里更是如此,在官方发布的库中就包含有做这件事情的库,那就是ConfigParser,这里简单的做一些介 ...

  8. 分享O'Reilly最新C语言指针数据

    1.推荐书名 Understanding.and.Using.C.Pointers.pdf 2. 本书目录 Table of Content Chapter 1. Introduction Chapt ...

  9. 线程操作API

    线程操作API 1.currentThread 2.getId() .getName().getPriority().getStart.isAlive().isDaemon().isInterrupt ...

  10. NOJ1066-堆排序

    堆排序 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 414            测试通过 : 220  比 ...