这是一道双标记线段树的题,很让人很好的预习/学习/复习线段树,我不知道它能让别人学习什么,反正让我对线段树的了解更加深刻。

  题目没什么好讲的,程序也没什么好讲的,所以也没有什么题解,但是值得一做

  给出题目&代码

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

 /**************************************************************
Problem: 1798
User: PencilWang
Language: C++
Result: Accepted
Time:4320 ms
Memory:27388 kb
****************************************************************/ #include<stdio.h>
long long n,m;
long long MOD;
struct shit{
int L,R;
long long num,j,c;
}s[];
long long w[];
long long C,J;
void fuck(int p)
{
s[p].num=(s[p<<].num+s[p<<|].num)%MOD;
return ;
}
void suck(int p)
{
int mid=(s[p].L+s[p].R)>>;
int LL=p<<,RR=p<<|;
s[LL].num=(s[LL].num*s[p].c+(s[LL].R-s[LL].L+)*s[p].j)%MOD;
s[LL].c=(s[LL].c*s[p].c)%MOD;
s[LL].j=(s[LL].j*s[p].c+s[p].j)%MOD;
s[RR].num=(s[RR].num*s[p].c+(s[RR].R-s[RR].L+)*s[p].j)%MOD;
s[RR].c=(s[RR].c*s[p].c)%MOD;
s[RR].j=(s[RR].j*s[p].c+s[p].j)%MOD;
s[p].c=,s[p].j=;
return ;
}
void build(int p,int l,int r)
{
s[p].L=l;
s[p].R=r;
s[p].c=;
s[p].j=;
if(l==r)
{
s[p].num=w[l];
return ;
}
int mid=(l+r)>>;
build(p<<,l,mid);
build(p<<|,mid+,r);
fuck(p);
return ;
}
void cc(int a,int b,int x,int p)
{
if(a<=s[p].L&&s[p].R<=b)
{
s[p].num=(x*s[p].num)%MOD;
s[p].c=(x*s[p].c)%MOD;
s[p].j=(x*s[p].j)%MOD;
return ;
}
suck(p);
int mid=(s[p].L+s[p].R)>>;
if(mid>=a)cc(a,b,x,p<<);
if(mid<b)cc(a,b,x,p<<|);
fuck(p);
return ;
}
void jj(int a,int b,int x,int p)
{
if(a<=s[p].L&&s[p].R<=b)
{
s[p].num=(s[p].num+x*(s[p].R-s[p].L+))%MOD;
s[p].j=(x+s[p].j)%MOD;
return ;
}
suck(p);
int mid=(s[p].L+s[p].R)>>;
if(mid>=a)jj(a,b,x,p<<);
if(mid<b)jj(a,b,x,p<<|);
fuck(p);
return ;
}
long long Q(int p,int a,int b)
{
if(a<=s[p].L&&s[p].R<=b)
return s[p].num%MOD;
int mid=(s[p].L+s[p].R)>>;
suck(p);
long long ANS=;
if(a<=mid)
{
ANS+=Q(p<<,a,b);
ANS%=MOD;
}
if(b>mid)
{
ANS+=Q(p<<|,a,b);
ANS%=MOD;
}
fuck(p);
return ANS;
}
int main()
{
long long a,b,c,f;
scanf("%lld%lld",&n,&MOD);
for(int i=;i<=n;i++)scanf("%lld",w+i);
build(,,n);
scanf("%lld",&m);
while(m--)
{
scanf("%lld%lld%lld",&f,&a,&b);
if(f==)
{
scanf("%lld",&c);
c%=MOD;
cc(a,b,c,);
}
else if(f==)
{
scanf("%lld",&c);
c%=MOD;
jj(a,b,c,);
}
else
printf("%lld\n",Q(,a,b)%MOD);
}
return ;
}

1798

值得一做》关于双标记线段树两三事BZOJ 1798 (NORMAL-)的更多相关文章

  1. [cogs2638]数列操作ψ(双标记线段树)

    题目大意:给定一个数列a,你需要支持的操作:区间and,区间or,询问区间最大值 解题关键: 1.双标记线段树,注意优先级(超时) 当涉及多重标记时,定义出标记的优先级,修改操作时用优先级高(先下放) ...

  2. 【双标记线段树】bzoj1798维护序列seq

    一.题目 描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列 ...

  3. 数据结构(线段树):BZOJ 3126: [Usaco2013 Open]Photo

    3126: [Usaco2013 Open]Photo Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 222  Solved: 116 Descrip ...

  4. 线段树合并 || BZOJ 5457: 城市

    题面:https://www.lydsy.com/JudgeOnline/problem.php?id=5457 题解: 线段树合并,对于每个节点维护sum(以该节点为根的子树中最大的种类和)和kin ...

  5. 【线段树】BZOJ 5334 数学计算

    题目内容 小豆现在有一个数\(x\),初始值为\(1\).小豆有\(Q\)次操作,操作有两种类型: 1 m:\(x=x×m\),输出\(x\ mod\ M\): 2 pos:\(x=x/\)第\(po ...

  6. bzoj 维护序列seq(双标记线段树)

    Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 4184  Solved: 1518[Submit][Status][Discus ...

  7. 主席树 || 可持久化线段树 || LCA || BZOJ 2588: Spoj 10628. Count on a tree || Luogu P2633 Count on a tree

    题面: Count on a tree 题解: 主席树维护每个节点到根节点的权值出现次数,大体和主席树典型做法差不多,对于询问(X,Y),答案要计算ans(X)+ans(Y)-ans(LCA(X,Y) ...

  8. 数据结构(线段树):BZOJ 1018: [SHOI2008]堵塞的交通traffic

    1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2638  Solved: 864 Descri ...

  9. BZOJ_1798_&_Codevs_2216_[AHOI_2009]_行星序列_(线段树)

    描述 BZOJ: http://www.lydsy.com/JudgeOnline/problem.php?id=1798 Codevs: http://codevs.cn/problem/2216/ ...

随机推荐

  1. 从零开始编写深度学习库(五)Eigen Tensor学习笔记2.0

    1.extract_image_patches函数的使用: 假设Eigen::Tensor形状为(3,8,8,9),现在要对第二维.第三维根据size大小为(2,2),stride=(2,2),那么如 ...

  2. js实现城市二级联动列表

    这个是一个同事写的,我看着有用,就cv下来了. 程序功能主要逻辑是: 1.当一级标签市显示默认状态 '-请选择-'时,二级标签要隐藏 2.一级标签选中城市时,二级标签显示在页面,并列出响应市区 3.当 ...

  3. 【Android】Android 学习记录贴

    官网 教程学习笔记 Genymotion 安卓虚拟器太慢,用Genymotion(装载eclipse的插件) 利用Genymotion运行Android应用程序 1.首先,点击 来启动或者创建您要使用 ...

  4. MySQL FEDERATED 存储引擎的使用

    FEDERATED 存储引擎描述 FEDERATED存储引擎能让你访问远程的MySQL数据库而不使用replication或cluster技术(类似于Oracle的dblink),使用FEDERATE ...

  5. asp.net core microservices 架构之 分布式自动计算(二)

    一  简介                   上一篇介绍了zookeeper如何进行分布式协调,这次主要讲解quartz使用zookeeper进行分布式计算,因为上一篇只是讲解原理,而这次实际使用, ...

  6. HWOJ-合唱队

    计算最少出列多少位同学,使得剩下的同学排成合唱队形 说明: N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依 ...

  7. SCARA——OpenGL入门学习五六(三维变换、动画)

    OpenGL入门学习(五) 此课为三维变换的内容,比较枯燥.主要是因为很多函数在单独使用时都不好描述其效果, 在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1到1,还只能 ...

  8. 关于setdefault和defaultdict

    c参考链接:http://blog.csdn.net/real_ray/article/details/17919289 defaultdict就是为没有的键给一个默认的值,实际是实现了一个__mis ...

  9. ASP.NET Cache缓存的使用

    ASP.NET Cache是提升系统性能的重要方法,它使用了“最近使用”原则(a least-recently-used algorithm).在数据库访问中经常会用到Cache保存数据库数据. 1. ...

  10. 异常mongodb:Invalid BSON field name XXXXXX:YYYYY.zz

    1.本周遇到这个问题. 定位到发现一个很神奇的现象上面的结构无法顺利以map的key值存入mongodb里面. 而且到线上才发现这个问题. 而且是部分用户才会出现这样的情况 大部分人的该数据是这样的 ...