线段树。。调的要死

1798: [Ahoi2009]Seq 维护序列seq

Time Limit: 30 Sec  Memory Limit: 64 MB
Submit: 3349  Solved: 1241
[Submit][Status][Discuss]

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

Source

program hehe;
type
shu=record
h,a,m:int64;
l,r:longint;
end;
var
n,q,t,m,i,j,k,f:longint;
x:array[0..1000000] of shu;

procedure build(a,l,r:longint);
var
mid:longint;
begin
x[a].l:=l;
x[a].r:=r;
x[a].m:=1;
if l=r then read(x[a].h)
else
begin
mid:=(l+r)>>1;
build(a<<1,l,mid);
build(a<<1+1,mid+1,r);
x[a].h:=(x[a<<1].h+x[a<<1+1].h)mod m;
end;
end;

procedure down(a:longint);
begin
if x[a].m<>1 then
begin
x[a<<1].m:=x[a<<1].m*x[a].m mod m;
x[a<<1+1].m:=x[a<<1+1].m*x[a].m mod m;
x[a<<1].a:=x[a<<1].a*x[a].m mod m;
x[a<<1+1].a:=x[a<<1+1].a*x[a].m mod m;
x[a<<1].h:=(x[a<<1].h mod m)*x[a].m mod m;
x[a<<1+1].h:=(x[a<<1+1].h mod m)*x[a].m mod m;
x[a].m:=1;
end;
if x[a].a<>0 then
begin
x[a<<1].a:=x[a<<1].a+x[a].a;
x[a<<1+1].a:=x[a<<1+1].a+x[a].a;
x[a<<1].h:=(x[a<<1].h+(x[a<<1].r-x[a<<1].l+1)*x[a].a)mod m;
x[a<<1+1].h:=(x[a<<1+1].h+(x[a<<1+1].r-x[a<<1+1].l+1)*x[a].a)mod m;
x[a].a:=0;
end;
end;

procedure cheng(a,l,r,b:longint);
var
mid:longint;
begin
down(a);
if (x[a].l=l)and(x[a].r=r) then
begin
x[a].m:=b;
x[a].h:=(x[a].h mod m)*b mod m;
end
else
begin
mid:=(x[a].l+x[a].r)>>1;
if l>mid then cheng(a<<1+1,l,r,b)
else if r<=mid then cheng(a<<1,l,r,b)
else
begin
cheng(a<<1,l,mid,b);
cheng(a<<1+1,mid+1,r,b);
end;
x[a].h:=(x[a<<1].h+x[a<<1+1].h)mod m;
end;
end;

procedure jia(a,l,r,b:longint);
var
mid:longint;
begin
down(a);
if (x[a].l=l)and(x[a].r=r) then
begin
x[a].a:=b;
x[a].h:=(x[a].h+(x[a].r-x[a].l+1)*b)mod m;
end
else
begin
mid:=(x[a].l+x[a].r)>>1;
if l>mid then jia(a<<1+1,l,r,b)
else if r<=mid then jia(a<<1,l,r,b)
else
begin
jia(a<<1,l,mid,b);
jia(a<<1+1,mid+1,r,b);
end;
x[a].h:=(x[a<<1].h+x[a<<1+1].h)mod m;
end;
end;

function find(a,l,r:longint):int64;
var
mid:longint;
begin
down(a);
if (x[a].l=l)and(x[a].r=r) then exit(x[a].h mod m);
mid:=(x[a].l+x[a].r)>>1;
if l>mid then exit(find(a<<1+1,l,r)mod m)
else if r<=mid then exit(find(a<<1,l,r)mod m)
else exit((find(a<<1,l,mid)+find(a<<1+1,mid+1,r))mod m);
end;

begin
readln(n,m);
build(1,1,n);
readln(q);
for i:=1 to q do
begin
read(j);
if j=1 then
begin
readln(k,f,t);
cheng(1,k,f,t);
end
else if j=2 then
begin
readln(k,f,t);
jia(1,k,f,t);
end
else
begin
readln(k,f);
writeln(find(1,k,f));
end;
end;
end.

时间: 2024-12-16 03:45:35

线段树。。调的要死的相关文章

PAT天梯赛练习题 L3-002. 堆栈(线段树查询第K大值)

L3-002. 堆栈 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 大家都知道“堆栈”是一种“先进后出”的线性结构,基本操作有“入栈”(将新元素插入栈顶)和“出栈”(将栈顶元素的值返回并从堆栈中将其删除).现请你实现一种特殊的堆栈,它多了一种操作叫“查中值”,即返回堆栈中所有元素的中值.对于N个元素,若N是偶数,则中值定义为第N/2个最小元:若N是奇数,则中值定义为第(N+1)/2个最小元. 输入格式: 输入第一行给出正整

bzoj1858 [Scoi2010]序列操作——线段树

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1858 线段树...调了一个上午...(后面带 // 的都是改出来的) lazy 标记的下放好麻烦,还得考虑赋值和取反的先后顺序什么的... 因为在取反时把赋值标记 swap 了,所以下放的时候先判断取反再判断赋值... 而且WA了一上午的原因竟然是一开始不慎把取反以为成翻转了,后来没改干净...那个 rev 的名字啊... 总之没有太改变自己最初的想法.改了些细节就A了还是很高兴的! 代码

cdoj841-休生伤杜景死惊开 (逆序数变形)【线段树 树状数组】

http://acm.uestc.edu.cn/#/problem/show/841 休生伤杜景死惊开 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 陆伯言军陷八卦阵之中,分明只是一条直路,却怎的也走不到尽头.阵中尽是石堆,以某一石堆为参考,无论向走还是向右,总是会回到出发的石堆,最后幸得一黄姓老翁带路才得脱出. 陆伯言逃离八卦阵后,来到山顶观察此

[CF787D]遗产(Legacy)-线段树-优化Dijkstra(内含数据生成器)

Problem 遗产 题目大意 给出一个带权有向图,有三种操作: 1.u->v添加一条权值为w的边 2.区间[l,r]->v添加权值为w的边 3.v->区间[l,r]添加权值为w的边 求st点到每个点的最短路 Solution 首先我们思考到,若是每次对于l,r区间内的每一个点都执行一次加边操作,不仅耗时还耗空间. 那么我们要想到一个办法去优化它.一看到lr区间,我们就会想到线段树对吧. 没错啦这题就是用线段树去优化它. 首先我们建一棵线段树,然后很容易想到,我们只需要把这一棵线段树当做

LUOGU P1505 [国家集训队]旅游 (树链剖分+线段树)

传送门 解题思路 快被调死的码农题,,,其实就是一个边权下放到点权的线段树+树剖. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> using namespace std; const int MAXN = 100005; const int inf = 0x3f3f3f3f; inline int rd(){

【BZOJ】1382: [Baltic2001]Mars Maps (线段树+扫描线)

1382: [Baltic2001]Mars Maps Time Limit: 5 Sec  Memory Limit: 64 MB Description 给出N个矩形,N<=10000.其坐标不超过10^9.求其面积并 Input 先给出一个数字N,代表有N个矩形. 接下来N行,每行四个数,代表矩形的坐标. Output 输出面积并 Sample Input 2 10 10 20 20 15 15 25 30 Sample Output 225 本以为是傻逼题,没想到不容易啊- 线段树+扫描

2017省夏令营Day7 【快速幂,筛法,矩阵快速幂,线段树】

题解:首先,我们可以得到一个规律:经过2次变换后,a和b的值都分别乘2了,所以只要用快速幂就能过啦,但是,要特判n为0的情况. 代码如下: 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define Mod 1000000007 5 using namespace std; 6 long long a,b,n,ans1,ans2; 7 long long power(long long x)

【bzoj3476-懒惰的奶牛】线段树

题解: 感觉这题和别人的做法不一样...呵呵呵...调了一百年.. 设家坐标为(a,b),对于每个点(x,y),可以转化为|a-x|+|b-y|<=k 对于每个点,它的影响范围是一个菱形(也就是一个正方形啦..),也就是一个图上有若干个正方形. 然后我就把这个坐标轴选择了45度. 好难画不画了,正交分解一下就可以了. 然后题目就转化成正方形各种交里的最大值. 正方形有x和y两个元素,但是很明显我们只能维护一个.. 所以我以x轴建立线段树,对于每个正方形按照y从小到大排序. 维护一个指针j,表示当

BZOJ_3196_二逼平衡树(树套树:线段树+Treap)

描述 可以处理区间问题的平衡树. 分析 树套树.可以用线段树套Treap.人生第一道树套树的题... op1:如果在整区间,直接在该区间的treap上求解.否则分两个区间求解,然后相加.最后+1. op2:这个不太好直接做,可以二分,每次假定一个值,用这个值去做op1,以此求得一个rank=k+1的数,求rank=k的数等价与求这个数的前驱pre. op3:先删后加. op4&op5:如果在整区间,直接在该区间的treap上求解,否则分量个区间求解,pre取最大值,suc取最小值.注意有些数在有

HDU 5316 Magician(线段树区间合并入门)

本文纯属原创,转载请注明出处谢谢.http://blog.csdn.net/zip_fan. 题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5316 Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description Fantasy magicians usually gain their ability