题目链接:https://atcoder.jp/contests/abl/tasks/abl_e
一开始有一个长度为 \(n\) 的全部为 \(1\) 的数列,要求支持区间覆盖为一个数 \(x(1\leq x\leq 9)\),以及求全部 \(n\) 个数字连起来 \(\bmod 998244353\)。
预处理出连续 \(k\) 个数字 \(1\sim 9\) 对 \(998244353\) 取模后的结果。以及 \(10^x\) 对 \(998244353\) 取模的结果。
然后线段树维护区间和即可。
时间复杂度 \(O(m\log n)\)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=200010,MOD=998244353;
ll n,Q;
ll mod[11][N],power[N];
struct Segtree
{
ll l[N*4],r[N*4],lazy[N*4];
ll sum[N*4];
void build(ll x,ll ql,ll qr)
{
l[x]=ql; r[x]=qr;
if (ql==qr)
{
sum[x]=1;
return;
}
ll mid=(ql+qr)>>1;
build(x*2,ql,mid); build(x*2+1,mid+1,qr);
sum[x]=(sum[x*2]*power[r[x*2+1]-l[x*2+1]+1]%MOD+sum[x*2+1])%MOD;
}
void pushdown(ll x)
{
if(lazy[x])
{
ll v=lazy[x]; lazy[x]=0;
sum[x*2]=mod[v][r[x*2]-l[x*2]+1];
sum[x*2+1]=mod[v][r[x*2+1]-l[x*2+1]+1];
lazy[x*2]=lazy[x*2+1]=v;
}
}
void update(ll x,ll ql,ll qr,ll v)
{
if (l[x]==ql && r[x]==qr)
{
sum[x]=mod[v][qr-ql+1];
lazy[x]=v;
return;
}
pushdown(x);
ll mid=(l[x]+r[x])>>1;
if (qr<=mid) update(x*2,ql,qr,v);
else if (ql>mid) update(x*2+1,ql,qr,v);
else update(x*2,ql,mid,v),update(x*2+1,mid+1,qr,v);
sum[x]=(sum[x*2]*power[r[x*2+1]-l[x*2+1]+1]%MOD+sum[x*2+1])%MOD;
}
}seg;
int main()
{
scanf("%lld%lld",&n,&Q);
power[1]=10;
for (ll i=2;i<=n;i++)
power[i]=power[i-1]*10%MOD;
for (ll i=1;i<=9;i++)
{
mod[i][1]=i;
for (ll j=2;j<N;j++)
mod[i][j]=(mod[i][j-1]*10+i)%MOD;
}
seg.build(1,1,n);
while (Q--)
{
ll ql,qr,x;
scanf("%lld%lld%lld",&ql,&qr,&x);
seg.update(1,ql,qr,x);
printf("%lld\n",seg.sum[1]);
}
return 0;
}
原文:https://www.cnblogs.com/stoorz/p/13737722.html