记录编号 |
553020 |
评测结果 |
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
题目名称 |
[SYOI 2018] 简单的线段树 |
最终得分 |
100 |
用户昵称 |
fw |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
12.501 s |
提交时间 |
2020-08-10 16:41:22 |
内存使用 |
23.75 MiB |
显示代码纯文本
#pragma GCC optimize (2)
#include <iostream>
#include <cstdio>
using namespace std;
namespace lsz {
typedef long long ll;
inline ll read () {
ll s = 0;
char ch = getchar ();
while (ch < '0' || ch > '9') ch = getchar ();
while (ch >= '0' && ch <= '9') s = (s << 3) + (s << 1) + ch - '0',ch = getchar ();
return s;
}
inline int read1 () {
int s = 0;
char ch = getchar ();
while (ch < '0' || ch > '9') ch = getchar ();
while (ch >= '0' && ch <= '9') s = (s << 3) + (s << 1) + ch - '0',ch = getchar ();
return s;
}
const int MAXN = 100001;
int n,m;
ll p;
ll a[MAXN] = {0};
struct Node {
ll l,r,sum,lz,mlz;
Node () {
l = r = sum = lz = 0;
mlz = 1;
}
}tree[4*MAXN];
void pushdown (ll i) {
long long k1 = tree[i].mlz,k2 = tree[i].lz;
tree[i<<1].mlz = (tree[i<<1].mlz * k1) %p;
tree[i<<1|1].mlz= (tree[i<<1|1].mlz * k1) %p;
tree[i<<1].lz = (k1 * tree[i<<1].lz + tree[i].lz) %p;
tree[i<<1|1].lz = (k1 * tree[i<<1|1].lz + tree[i].lz) %p;
tree[i<<1].sum = (tree[i<<1].sum * k1 + (tree[i<<1].r - tree[i<<1].l + 1) * k2) %p;
tree[i<<1|1].sum= (tree[i<<1|1].sum * k1 + (tree[i<<1|1].r - tree[i<<1|1].l + 1) * k2) %p;
tree[i].lz = 0;
tree[i].mlz = 1;
return ;
}
void build(ll i,int l,int r) {
tree[i].l = l; tree[i].r = r;
if (l == r) {
tree[i].sum = a[l];
return ;
}
int mid = (l + r) >> 1;
build (i << 1,l,mid);
build (i << 1 | 1,mid + 1,r);
tree[i].sum = tree[i << 1].sum + tree[i << 1 | 1].sum;
return ;
}
ll search (ll i,int l,int r) {
if (tree[i].l >= l && tree[i].r <= r) {
return tree[i].sum % p;
}
if (tree[i].l > r || tree[i].r < l) return 0;
pushdown (i);
ll s=0;
if (tree[i << 1].r >= l) s += search(i << 1,l,r) % p;
if (tree[i << 1 | 1].l <= r) s += search(i << 1 | 1,l,r) % p;
return s % p;
}
void add (ll i,int l,int r,ll k) {
if (tree[i].l >= l && tree[i].r <= r) {
tree[i].sum = (tree[i].sum + k * (tree[i].r - tree[i].l + 1)) % p;
tree[i].lz = (tree[i].lz + k) % p;
return ;
}
if (tree[i].l > r || tree[i].r < l) return ;
pushdown (i);
if (tree[i << 1].r >= l) add(i << 1,l,r,k);
if (tree[i << 1 | 1].l <= r) add(i << 1 | 1,l,r,k);
tree[i].sum = (tree[i << 1].sum % p + tree[i << 1 | 1].sum % p) % p;
return ;
}
void mul (ll i,int l,int r,ll k) {
if (tree[i].l >= l && tree[i].r <= r) {
tree[i].sum = (tree[i].sum * k) % p;
tree[i].mlz = (tree[i].mlz * k) % p;
tree[i].lz = (tree[i].lz * k) % p;
return ;
}
if (tree[i].l > r || tree[i].r < l) return ;
pushdown (i);
if (tree[i << 1].r >= l) mul (i << 1,l,r,k);
if (tree[i << 1 | 1].l <= r) mul (i << 1 | 1,l,r,k);
tree[i].sum = (tree[i << 1].sum % p + tree[i << 1 | 1].sum % p) % p;
return ;
}
}
using namespace lsz;
int Main () {
freopen("easilysegmenttree.in","r",stdin);
freopen("easilysegmenttree.out","w",stdout);
n = read1 ();
m = read1 ();
p = read ();
build (1,1,n);
int cm;
int a,b,c;
for (int q = 1;q <= m;++ q) {
cm = read1 ();
if (cm == 1) {
a = read1 ();
b = read1 ();
c = read1 ();
add (1,a,b,c);
}
if (cm == 2) {
a = read1 ();
b = read1 ();
c = read1 ();
mul (1,a,b,c);
}
if (cm == 3) {
a = read1 ();
b = read1 ();
printf ("%lld\n",search (1,a,b) % p);
}
}
return 0;
}
int ss = Main ();
int main () {;}