AT_abl_e 的题解
(一)
线段树裸题。
可以开两个辅助数组,分别表示 \(10^i\) 和 \(\sum_{j=0}^{i}10^j\)。
线段树上每一个节点表示该区间的值,可用第一个数组进行拼合。
区间覆盖可以用懒标记和第二个数组处理。
(二)
记得开 long long。
AC 代码。
#include<bits/stdc++.h>
#define db double
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define pii pair<int,int>
#define int long long
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int mxn=3e5+10,md=998244353;
int s0[mxn],s1[mxn],tree[mxn<<2],tag[mxn<<2];
void build(int o,int l,int r){
tree[o]=s1[r-l+1];
tag[o]=-1;
if(l==r)return;
int mid=(l+r)>>1;
build(o*2,l,mid);
build(o*2+1,mid+1,r);
}
void change(int o,int l,int r,int val){
tree[o]=s1[r-l+1]*val%md;
tag[o]=val;
}
void pushdown(int o,int l,int r){
if(tag[o]==-1)return;
int mid=(l+r)>>1;
change(o*2,l,mid,tag[o]);
change(o*2+1,mid+1,r,tag[o]);
tag[o]=-1;
}
void update(int o,int l,int r,int L,int R,int val){
if(L<=l&&r<=R){
change(o,l,r,val);
return;
}
pushdown(o,l,r);
int mid=(l+r)>>1;
if(L<=mid)update(o*2,l,mid,L,R,val);
if(R>mid)update(o*2+1,mid+1,r,L,R,val);
tree[o]=(tree[o*2]*s0[r-mid]%md+tree[o*2+1])%md;
}
signed main(){
int n=read(),q=read();
s0[0]=1;
for(int i=1;i<=n;i++)
s0[i]=s0[i-1]*10%md;
s1[1]=1;
for(int i=2;i<=n;i++)
s1[i]=(s1[i-1]*10%md+1)%md;
build(1,1,n);
while(q--){
int l=read(),r=read(),v=read();
update(1,1,n,l,r,v);
printf("%lld\n",tree[1]);
}
return 0;
}