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;
}
posted @ 2024-07-30 00:34  Jerry_heng  阅读(9)  评论(0编辑  收藏  举报