记录编号 |
585550 |
评测结果 |
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
题目名称 |
[SYOI 2018] 简单的线段树 |
最终得分 |
100 |
用户昵称 |
┭┮﹏┭┮ |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
12.368 s |
提交时间 |
2023-12-16 16:41:35 |
内存使用 |
0.00 MiB |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
ll n,m,p;
ll a[N];
struct SegentTree{
int l,r;
ll sum,add,mul;
#define l(x) t[x].l
#define r(x) t[x].r
#define sum(x) t[x].sum
#define add(x) t[x].add
#define mul(x) t[x].mul
}t[N<<2];
void pushup(int x){
sum(x) = (sum(x<<1) + sum(x<<1|1)) % p;
}
void pushdown(int x){
if(mul(x) != 1){
mul(x<<1) = (mul(x<<1) * mul(x)) % p;
mul(x<<1|1) = (mul(x<<1|1) * mul(x)) % p;
sum(x<<1) = (sum(x<<1) * mul(x)) % p;
sum(x<<1|1) = (sum(x<<1|1) * mul(x)) % p;
add(x<<1) = (add(x<<1) * mul(x)) % p;
add(x<<1|1) = (add(x<<1|1) * mul(x)) % p;
mul(x) = 1;
}//!!
if(add(x) != 0){
add(x<<1) = (add(x<<1) + add(x)),add(x<<1|1) = (add(x<<1|1) + add(x)) % p;
sum(x<<1) = (sum(x<<1) + add(x) * (r(x<<1) - l(x<<1) + 1) % p) % p;
sum(x<<1|1) = (sum(x<<1|1) + add(x) * (r(x<<1|1) - l(x<<1|1) + 1) % p) % p;
add(x) = 0;
}
}
void build(int x,int l,int r){
l(x) = l,r(x) = r;mul(x) = 1;
if(l == r){
sum(x) = a[l] % p;
return;
}
int mid = l + r >> 1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
void modifyadd(int x,int l,int r,ll z){
if(l <= l(x) && r(x) <= r){
add(x) = (add(x) + z) % p;
sum(x) = (sum(x) + z * (r(x) - l(x) + 1) % p) % p;
return;
}
pushdown(x);
int mid = l(x) + r(x) >> 1;
if(l <= mid)modifyadd(x<<1,l,r,z);
if(r > mid)modifyadd(x<<1|1,l,r,z);
pushup(x);
}
void modifymul(int x,int l,int r,ll z){
if(l <= l(x) && r(x) <= r){
mul(x) = (mul(x) * z) % p;
add(x) = (add(x) * z) % p;
sum(x) = (sum(x) * z) % p;
return;
}
pushdown(x);
int mid = l(x) + r(x) >> 1;
if(l <= mid)modifymul(x<<1,l,r,z);
if(r > mid)modifymul(x<<1|1,l,r,z);
pushup(x);
}
ll ask(int x,int l,int r){
if(l <= l(x) && r(x) <= r)return sum(x);
pushdown(x);
int mid = l(x) + r(x) >> 1;ll ans = 0;
if(l <= mid)ans = (ans + ask(x<<1,l,r)) % p;
if(r > mid)ans = (ans + ask(x<<1|1,l,r)) % p;
return ans;
}
int main(){
freopen("easilysegmenttree.in","r",stdin);
freopen("easilysegmenttree.out","w",stdout);
scanf("%lld%lld%lld",&n,&m,&p);
build(1,1,n);
for(int i = 1;i <= m;i++){
int op,x,y;ll z;
scanf("%d%d%d",&op,&x,&y);
if(op == 2){
scanf("%lld",&z);
modifymul(1,x,y,z);
}
else if(op == 1){
scanf("%lld",&z);
modifyadd(1,x,y,z);
}
else printf("%lld\n",ask(1,x,y));
}
return 0;
}