线段树

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

  要打两种标记:乘法和加法标记。一开始我想着可以像只有加法标记那样,永不下传,查询的时候依次累加就好了。后来发现不会写……只好每次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. 微软必应·英雄会第三届在线编程大赛:几个bing?

    发布公司:微软亚太研发集团 有 效 期:2013-12-31至2014-02-01 难 度 等 级: 答 题 时 长:120分钟 编程语言要求:C C++ Java C# 悬赏详情 一等奖 : 价值2 ...

  2. spark性能调优:资源优化

    在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都可以在spark-submit命令中作为参数设置.很多Spark初学者,通常不知道该设置哪些必要的参数,以及如何设置 ...

  3. CDH 不能监控hadoop状态

    1 背景:公司集群整体搬迁 2 问题:hadoop重启后,发现一个非常坑爹的问题.用 hadoop dfsadmin -report 查看datanode状态完全正常,但是Cloudera Manag ...

  4. 小课堂week14 Google软件测试之道

    读<Google软件测试之道> 在IT领域,Google是一面旗帜,是一家非常善于思考善于尝试的公司.随着面临挑战的不断增大,传统的测试开展方式也越来越力不从心,这本书讲述的就是一次完整的 ...

  5. Keil(MDK-ARM)使用教程(三)_在线调试

    Ⅰ.概述 该文章总结Keil(MDK-ARM)在线调试相关的内容,详情请往下看. 该文章是基于新建好软件工程来讲述,关于Keil的下载.安装和新建工程我已将在前面做了详细的总结,不懂的可以参看我博客里 ...

  6. pure css做的pc登陆界面

    源码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...

  7. 推荐一个sqlce,sqllite等数据库管理工具

    推荐一个sqlce,sqllite等数据库管理工具 下载地址: http://fishcodelib.com/files/DatabaseNet4.zip 支持sqlserver,sqlce, sql ...

  8. 使用Linux调用资源库中的Job报错-ERROR: No repository provided, can't load job.

    使用kettle调用资源库中的作业或者是转换,需要注意一下两个问题: 问题一:(-rep后不需要IP)标准shell代码如下 #!/bin/bash export JAVA_HOME=/usr/lib ...

  9. 在mac系统安装Apache Tomcat的详细步骤[转]

    对于Apache Tomcat 估计很多童鞋都会,那么今天就简单说下在mac上进行tomcat的安装: 第一步:下载Tomcat   这里Himi下载的tomcat version:7.0.27 直接 ...

  10. expdp与impdp

    参考http://blog.csdn.net/hello985/article/details/13295305 (一)        导出scott用户下的emp表到xx用户下 1.1      创 ...