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

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

  给出题目&代码

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. AlexNet神经网络结构

    Alexnet是2014年Imagenet竞赛的冠军模型,准确率达到了57.1%, top-5识别率达到80.2%. AlexNet包含5个卷积层和3个全连接层,模型示意图: 精简版结构: conv1 ...

  2. Oracle新用户以及授权的若干问题

    Database 实验4 问题: 授权语句 grant create table to user_name; 收回授权语句 revoke create table from user_name; 注意 ...

  3. (七)java转译字符与连接字符串

    转义字符:通过“\”来改变后面字符的意义 \n空格 \t相当于table键 \b相当于回退 class Zyzf { public static void main(String[] args) { ...

  4. LINUX下的ssh登录之后的文件远程copy:scp命令(接前文ssh登录)

    先记录参考: 1:http://www.cnblogs.com/peida/archive/2013/03/15/2960802.html 2:http://www.vpser.net/manage/ ...

  5. [HAL]5.中断里调用HAL_Delay()进入死循环的原因

    中断里调用HAL_Delay()进入死循环的原因  摘自:http://blog.csdn.net/alwxkxk/article/details/47204677 CUBE生成的程序中, SysTi ...

  6. 解决"hibernate.hbm2ddl.auto" update值 无效

    <property name="schemaUpdate"> <value>true</value> </property> 若果是 ...

  7. egg 使用手记(一)

    1. 文件加载规则 引用官方的说法: 框架在加载文件时会进行转换,因为文件命名风格和 API 风格存在差异.我们推荐文件使用下划线,而 API 使用驼峰.比如 app/service/user_inf ...

  8. codeforce 977 F. Consecutive Subsequence

    F. Consecutive Subsequence time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  9. chrome打开新标签页插件

    标签(空格分隔): 日常办公,chrome浏览器 一直被chrome浏览器打开新标签页困扰,每次点开一个新标签页还要再去点一下主页,才能打开搜索页面.如果直接点击主页,又会把当前的页面刷掉,实在是非常 ...

  10. 1088 Rational Arithmetic

    题意: 给出两个分式(a1/b1 a2/b2),分子.分母的范围为int型,且确保分母不为0.计算两个分数的加减乘除,结果化为最简的形式,即"k a/b",其中若除数为0的话,输出 ...