【ATcoder】Replace Digits

题目

题目链接: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;
}

posted @ 2020-09-27 09:26  stoorz  阅读(185)  评论(0编辑  收藏  举报