##Segment Tree Template
作者:互联网
馅断术模板啦~
已知一个数列,你需要进行下面三种操作:
将某区间每一个数乘上x
将某区间每一个数加上x
求出某区间每一个数的和
输入格式
第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。
第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
接下来M行每行包含3或4个整数,表示一个操作,具体如下:
操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k
操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k
操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果
输出格式
输出包含若干行整数,即为所有操作3的结果。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <memory.h>
#define ll long long
using namespace std;
const int maxn = 100005;
const int maxm = 1000005;
ll a[maxn];
ll sum[maxm];
ll addv[maxm];
ll mulv[maxm];
int p;
inline ll read()
{
char c = getchar(); ll x = 0;
for (; !isdigit(c); c = getchar());
for (; isdigit(c); c = getchar())
x = x * 10 + (c - '0');
return x;
}
void cons(int o, int L, int R)
{
addv[o] = 0;
mulv[o] = 1;
if (L == R)
sum[o] = a[L];
else
{
int mid = (L + R) / 2;
cons(o * 2, L, mid);
cons(o * 2 + 1, mid + 1, R);
sum[o] = sum[o * 2] + sum[o * 2 + 1];
}
sum[o] %= p;
return;
}
inline void maintain(int o, int L, int R)
{
int mid = (L + R) / 2;
sum[o * 2] = (sum[o * 2] * mulv[o] + addv[o] * (mid - L + 1)) % p;
sum[o * 2 + 1] = (sum[o * 2 + 1] * mulv[o] + addv[o] * (R - mid)) % p;
mulv[o * 2] = (mulv[o] * mulv[o * 2]) % p;
mulv[o * 2 + 1] = (mulv[o] * mulv[o * 2 + 1]) % p;
addv[o * 2] = (addv[o * 2] * mulv[o] + addv[o]) % p;
addv[o * 2 + 1] = (addv[o * 2 + 1] * mulv[o] + addv[o]) % p;
addv[o] = 0;
mulv[o] = 1;
}
ll ql, qr;
void u_add(int o, int L, int R, int d)
{
if (R<ql || L>qr)return;
if (ql <= L && R <= qr)
{
addv[o] = (addv[o] + d) % p;
sum[o] = (sum[o] + d * (R - L + 1)) % p;
return;
}
maintain(o, L, R);
int mid = (L + R) / 2;
u_add(2 * o, L, mid, d);
u_add(2 * o + 1, mid + 1, R, d);
sum[o] = (sum[o * 2] + sum[o * 2 + 1]) % p;
return;
}
void u_mul(int o, int L, int R, int m)
{
if (R<ql || L>qr)return;
if (ql <= L && R <= qr)
{
sum[o] = (sum[o] * m) % p;
addv[o] = (addv[o] * m) % p;
mulv[o] = (mulv[o] * m) % p;
return;
}
maintain(o, L, R);
int mid = (L + R) / 2;
u_mul(2 * o, L, mid, m);
u_mul(2 * o + 1, mid + 1, R, m);
sum[o] = (sum[o * 2] + sum[o * 2 + 1]) % p;
return;
}
ll query(int o, int L, int R)//intial d=0,m=1;
{
if (R<ql || L>qr)return 0;
if (ql <= L && R <= qr)
return sum[o];
ll s1 = 0, s2 = 0;
maintain(o, L, R);
int mid = (L + R) / 2;
s1 = query(2 * o, L, mid);
s2 = query(2 * o + 1, mid + 1, R);
return (s1 + s2) % p;
}
int main()
{
memset(mulv, 1, sizeof(mulv));
int n, m;
cin >> n >> m >> p;
for (int i = 1; i <= n; i++)
a[i] = read();
cons(1, 1, n);
for (int i = 1; i <= m; i++)
{
ll g = 0;
g = read();
ql = read();
qr = read();
if (g == 1)
{
int k = read();
u_mul(1, 1, n, k);
continue;
}
if (g == 2)
{
int k = read();
u_add(1, 1, n, k);
continue;
}
if (g == 3)
{
ll s = query(1, 1, n);
printf("%d\n", s);
continue;
}
}
return 0;
}
标签:addv,##,mulv,sum,Tree,mid,int,Segment,ll 来源: https://www.cnblogs.com/kion/p/11819405.html