D - The Child and Sequencehttps://vjudge.net/contest/503800#problem/D
本题甚至不用设置lazytag,只需给传统线段树的基础上维护一个区间最大值,如果区间最大值小于要取模数,那么就不用继续对向下的结点进行操作,否则,我们就递归到叶子结点进行更新。从而大幅度优化时间复杂度。
#include <bits/stdc++.h>
#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC optimize(2)
#define ll long long
#define int long long
#define endl '\n'
#define PII pair<int, int>
using namespace std;
const int N = 2e5 + 10, INF = 0x3f3f3f3f, mod = 1e9 + 7;
int read() {
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
void write(int x) {
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
struct node
{
int l, r;
int sum;
int maxx;
}t[N<<2];
int a[N];
void pushup(int p)
{
t[p].sum = t[p << 1].sum + t[p << 1 | 1].sum;
t[p].maxx = max(t[p << 1].maxx, t[p << 1 | 1].maxx);
}
void build(int p,int l,int r)
{
t[p] = {l, r,0, 0};
if(l==r)
{
t[p].sum = a[l];
t[p].maxx = a[l];
return;
}
int mid = l + r >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
pushup(p);
}
void modify(int p,int l,int r,int x)
{
if(t[p].l>=l&&t[p].r<=r&&t[p].maxx<x)return;
if(t[p].l==t[p].r)
{
t[p].sum %= x;
t[p].maxx = t[p].sum;
return;
}
if(t[p<<1].r>=l)
modify(p << 1, l, r,x);
if(t[p<<1|1].l<=r)
modify(p << 1 | 1, l, r,x);
pushup(p);
}
void update(int p,int f,int x)
{
if (t[p].l == t[p].r)
{
t[p].sum = x;
t[p].maxx = x;
return;
}
if(f<=t[p<<1].r)
update(p << 1, f, x);
else
update(p << 1 | 1, f, x);
pushup(p);
}
int query(int p,int l,int r)
{
if(t[p].l>=l&&t[p].r<=r)
{
return t[p].sum;
}
int res = 0;
if(t[p<<1].r>=l)
res+=query(p << 1, l, r);
if(t[p<<1|1].l<=r)
res+=query(p << 1 | 1, l, r);
return res;
}
signed main()
{
int n,m;
n = read();
m = read();
for (int i = 1; i <= n;i++){
a[i] = read();
}
build(1, 1, n);
while(m--)
{
int op;
op=read();
if(op==1)
{
int l, r;
l = read(), r = read();
write(query(1, l, r));
puts("");
}
else if(op==2)
{
int l, r, x;
l = read(), r = read(), x = read();
modify(1, l, r, x);
}
else if(op==3)
{
int f, x;
f = read(), x = read();
update(1, f, x);
}
}
return 0;
}