【codevs2216】行星序列 线段树 区间两异同修改+区间求和*****

时间:2022-09-19 15:15:23

【codevs2216】行星序列

2014年2月22日3501

题目描述 Description

“神州“载人飞船的发射成功让小可可非常激动,他立志长大后要成为一名宇航员假期一始,他就报名参加了“小小宇航员夏令营”,在这里小可可不仅学到了丰富的宇航知识,还参与解决了一些模拟飞行中发现的问题,今天指导老师交给他一个任务,在这次模拟飞行的路线上有N个行星,暂且称它们为一个行星序列,并将他们从1至n标号,在宇宙未知力量的作用下这N个行星的质量是不断变化的,所以他们对飞船产生的引力也会不断变化,小可可的任务就是在飞行途中计算这个行星序列中某段行星的质量和,以便能及时修正飞船的飞行线路,最终到达目的地,行星序列质量变化有两种形式:

1,行星序列中某一段行星的质量全部乘以一个值

2,行星序列中某一段行星的质量全部加上一个值

由于行星的质量和很大,所以求出某段行星的质量和后只要输出这个值模P的结果即可,小可可被这个任务难住了,聪明的你能够帮他完成这个任务吗?

输入描述 Input Description

第一行两个整数N和P(1<=p<=1000000000);

第二行含有N个非负整数,从左到右依次为a1,a2,…………,an(0<=ai<=100000000,1<=i<=n),其中ai表示第i个行星的质量:

第三行有一个整数m,表示模拟行星质量变化以及求质量和等操作的总次数。从第四行开始每行描述一个操作,输入的操作有以下三种形式:

操作1:1 t g c 表示把所有满足t<=i<=g的行星质量ai改为ai*c

操作2:2 t g c 表示把所有满足t<=i<=g的行星质量ai改为ai+c

操作3:3 t g 表示输出所有满足t<=i<=g的ai的和模p的值

其中:1<=t<=g<=N,0<=c<=10000000

注:同一行相邻的两数之间用一个空格隔开,每行开头和末尾没有多余空格

输出描述 Output Description

对每个操作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

数据范围及提示 Data Size & Hint

100%的数据中,M,N<=100000

40%的数据中,M,N<=10000

题解

这两种修改可能会造成冲突`!!!!!!

long long

代码

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <queue>
#include <typeinfo>
#include <map>
#include <stack>
typedef long long ll;
#define inf 0x7fffffff
using namespace std;
inline ll read()
{
ll x=,f=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-')f=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
x=x*+ch-'';
ch=getchar();
}
return x*f;
} //************************************************************************************** struct ss
{
int l,r;
ll sum;
ll lazyc,lazyj;
} tr[*];
int n;
int p;
ll a[];
void build(int k,int s,int t)
{
tr[k].l=s;
tr[k].r=t;
tr[k].lazyc=;
if(s==t)
{
tr[k].sum=a[s]%p;
return;
}
int mid=(s+t)>>;
build(k<<,s,mid);
build(k<<|,mid+,t);
tr[k].sum=(tr[k<<].sum+tr[k<<|].sum)%p;
}
void pushdown(int k)
{
if(tr[k].l==tr[k].r)return;
int t=tr[k].r-tr[k].l+;
ll m=tr[k].lazyc;
ll a=tr[k].lazyj;
tr[k<<].sum=(tr[k<<].sum*m+(t-(t>>))*a)%p;
tr[k<<|].sum=(tr[k<<|].sum*m+(t>>)*a)%p;
tr[k<<].lazyj=(tr[k<<].lazyj*m+a)%p;
tr[k<<|].lazyj=(tr[k<<|].lazyj*m+a)%p;
tr[k<<].lazyc=(tr[k<<].lazyc*m)%p;
tr[k<<|].lazyc=tr[k<<|].lazyc*m%p;
tr[k].lazyj=;
tr[k].lazyc=;
}
void update1(int k,int s,int t,ll c)
{
pushdown(k);
if(s==tr[k].l&&t==tr[k].r)
{
tr[k].sum=(tr[k].sum*c)%p;
tr[k].lazyc=(tr[k].lazyc*c)%p;
return;
}
int mid=(tr[k].l+tr[k].r)>>;
if(t<=mid)
{
update1(k<<,s,t,c);
}
else if(s>mid)update1(k<<|,s,t,c);
else
{
update1(k<<,s,mid,c);
update1(k<<|,mid+,t,c);
}
tr[k].sum=(tr[k<<].sum+tr[k<<|].sum)%p;
}
void update2(int k,int s,int t,ll c)
{
pushdown(k);
if(s==tr[k].l&&t==tr[k].r)
{
tr[k].sum=(tr[k].sum+c*(t-s+))%p;
tr[k].lazyj=(tr[k].lazyj+c)%p;
return;
}
int mid=(tr[k].l+tr[k].r)>>;
if(t<=mid)
{
update2(k<<,s,t,c);
}
else if(s>mid)update2(k<<|,s,t,c);
else
{
update2(k<<,s,mid,c);
update2(k<<|,mid+,t,c);
}
tr[k].sum=(tr[k<<].sum+tr[k<<|].sum)%p;
}
long long ask(int k,int s,int t)
{
pushdown(k);
ll ans;
if(s==tr[k].l&&t==tr[k].r)
{
return tr[k].sum;
}
int mid=(tr[k].l+tr[k].r)>>;
if(t<=mid)ans=ask(k<<,s,t);
else if(s>mid) ans=ask(k<<|,s,t);
else
{
ans=(ask(k<<,s,mid)+ask(k<<|,mid+,t))%p;
}
tr[k].sum=(tr[k<<].sum+tr[k<<|].sum)%p;
return ans;
}
int main()
{ scanf("%d%d",&n,&p);
for(int i=; i<=n; i++)
{
scanf("%lld",&a[i]);
}
build(,,n);
int m;
scanf("%d",&m);
for(int i=; i<=m; i++)
{
int t;
int x,y,z;
scanf("%d",&t);
if(t==)
{
scanf("%d%d%d",&x,&y,&z);
update1(,x,y,z);
for(int j=; j<n; j++)
{
printf("%d ",tr[j+].sum);
}
/* printf("%d\n",tr[7].sum);
printf("5->6lazyc:%d\n",tr[6].lazyc);
printf("5->6lazyj:%d\n",tr[6].lazyj);
printf("5->7lazyj:%d\n",tr[3].lazyj);*/
}
else if(t==)
{
scanf("%d%d%d",&x,&y,&z);
update2(,x,y,z);
for(int j=; j<n; j++)
{
printf("%d ",tr[j+].sum);
}
/* printf("%d\n",tr[7].sum);
printf("5->6lazyc:%d\n",tr[6].lazyc);
printf("5->6lazyj:%d\n",tr[6].lazyj);
printf("5->7lazyj:%d\n",tr[3].lazyj);*/
}
else
{
scanf("%d%d",&x,&y);
printf("%lld\n",ask(,x,y)%p);
for(int j=; j<n; j++)
{
printf("%d ",tr[j+].sum);
}
/*printf("%d\n",tr[7].sum);
printf("5->6lazyc:%d\n",tr[6].lazyc);
printf("5->6lazyj:%d\n",tr[6].lazyj);
printf("5->7lazyj:%d\n",tr[3].lazyj);*/
/* for(int i=1;i<n;i++)
{
printf("%d ",tr[i+7].sum);
}
printf("%d\n",tr[7].sum);
if(i)
{
printf("5->7:%d\n",tr[3].sum);
printf("5->7lazyc:%d\n",tr[3].lazyc);
printf("5->7lazyj:%d\n",tr[3].lazyj);
}*/
}
}
return ;
}