atcoder abl_e
https://atcoder.jp/contests/abl/tasks/abl_e
输入 n(≤2e5) 和 q(≤2e5)。
初始有一个长为 n 的字符串 s,所有字符都是 1,s 的下标从 1 开始。
然后输入 q 个替换操作,每个操作输入 L,R (1≤L≤R≤n) 和 d (1≤d≤9)。
你需要把 s 的 [L,R] 内的所有字符替换为 d。
对每个操作,把替换后的 s 看成一个十进制数,输出这个数模 998244353 的结果。
输入
8 5
3 6 2
1 4 7
3 8 3
2 2 2
4 5 1
输出
11222211
77772211
77333333
72333333
72311333
输入
200000 1
123 456 7
输出
641437905
珂朵莉树练习题。
预处理 11...1 (i 个 1) 以及 10^i 的值,就可以套模板了,核心在于更新答案的逻辑。
比如把 111xxx 替换成 333xxx,那么 ans 增加了 (3-1)1111000。
#include<iostream>
#include<set>
using namespace std;
typedef long long ll;
ll res=0;
ll p[200005]={};
ll mp[200005]={};
int n,q;
const ll mod=998244353;
struct Node {
int l,r;
mutable int v;
Node(int l,int r,int v):l(l),r(r),v(v) {}
bool operator<(const Node &o) const {return l<o.l;}
};
set<Node>tree;
void init(int n){
for(int j=1;j<=n;j++)
p[j]=(p[j-1]*10+1)%mod;
mp[0]=1;
for(int j=1;j<=n;j++)
mp[j]=(mp[j-1]*10)%mod;
res=p[n];
}
auto split(int pos){
if(pos > tree.rbegin()->r) return tree.end();
auto it=tree.lower_bound(Node(pos,0,0));
if(it!=tree.end()&&it->l==pos) return it;
it--;
int l=it->l,r=it->r,v=it->v;
tree.erase(it);
tree.insert(Node(l,pos-1,v));
return tree.insert(Node(pos,r,v)).first;
}
void assign(int l,int r, int v){
auto end=split(r+1),begin=split(l);
for(auto it=begin;it!=end;it++){
res=(res+mod+((p[it->r-it->l+1]*(v-it->v))%mod*mp[n-it->r])%mod)%mod;
}
tree.erase(begin,end);
tree.insert(Node(l,r,v));
}
int main(){
cin>>n>>q;
init(n);
tree.insert(Node(1,n,1));
while(q--){
int l,r,d;
scanf("%d %d %d",&l,&r,&d);
assign(l,r,d);
printf("%lld\n",res);
}
system("pause");
}