题意:初始化给定n个空串,每次有两个操作:
wrap l r d : change Si To dSid (l=<i<=r)
query l r :
题解:对于一个数字x若执行第一个操作则
则若对于一个区间sum(l,r)执行第一个操作则
![]()
设
则便可以用线段树去维护这两个东西便可,这里只考虑了d是一位数的情况,但是在线段树下传标记的过程中可能一个区间多次执行第一个操作,那么wrap的d便不是一位数,而且左右两边的d是镜像的,我们便要用两个lazy标记,lazy1维护左边加的数,lazy2维护右边加的数,同时可以用lazylen表示这两个lazy的
,然后好好考虑一下如何维护sum和sumlen即可
#include<bits/stdc++.h>
using namespace std;
#define Sheryang main
#define TYPE int
const int maxn=2e5+7;
typedef long long ll;
const int mod=1e9+7;
void Smax(TYPE &a,TYPE b){if(a<b) a=b;}
void Smin(TYPE &a,TYPE b){if(a>b) a=b;}
///#define getchar()(p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
///char buf[(1 << 21) + 1], *p1 = buf, *p2 = buf;
#define IO cin.tie(0),ios::sync_with_stdio(false);
#define pi acos(-1)
#define PII pair<ll,ll>
ll read(){ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
#define read read()
/** keep hungry and keep calm! **/
ll sum[maxn<<2],pos[maxn<<2],lazy1[maxn<<2],lazy2[maxn<<2],lazylen[maxn<<2];
// pos[rt] = 10^len(a[l]) + ... + 10^len(a[r])
int n;
void pushdown(int rt,int l,int r){
if(lazylen[rt]>1){
lazy1[rt<<1] = (lazy1[rt]*lazylen[rt<<1] + lazy1[rt<<1])%mod;
lazy1[rt<<1|1] = (lazy1[rt]*lazylen[rt<<1|1] + lazy1[rt<<1|1])%mod;
lazy2[rt<<1] = (lazy2[rt<<1]*lazylen[rt] + lazy2[rt])%mod;
lazy2[rt<<1|1] = (lazy2[rt<<1|1]*lazylen[rt] + lazy2[rt])%mod;
int mid = l+r>>1;
sum[rt<<1] = lazy1[rt]*pos[rt<<1]%mod*lazylen[rt]%mod + sum[rt<<1]*lazylen[rt]%mod + lazy2[rt]*(mid-l+1)%mod;
sum[rt<<1] %= mod;
sum[rt<<1|1] = lazy1[rt]*pos[rt<<1|1]%mod*lazylen[rt]%mod + sum[rt<<1|1]*lazylen[rt]%mod + lazy2[rt]*(r-mid)%mod;
sum[rt<<1|1] %= mod;
pos[rt<<1] = (pos[rt<<1]*lazylen[rt]%mod*lazylen[rt])%mod;
pos[rt<<1|1] = (pos[rt<<1|1]*lazylen[rt]%mod*lazylen[rt])%mod;
lazylen[rt<<1] = (lazylen[rt<<1]*lazylen[rt])%mod;
lazylen[rt<<1|1] = (lazylen[rt<<1|1]*lazylen[rt])%mod;
lazy1[rt] = lazy2[rt] = 0;
lazylen[rt] = 1;
}
}
void pushup(int rt){
pos[rt] = (pos[rt<<1] + pos[rt<<1|1])%mod;
sum[rt] = (sum[rt<<1] + sum[rt<<1|1])%mod;
}
void build(int rt=1,int l=1,int r=n){
sum[rt] = 0;
lazy1[rt] = lazy2[rt] = 0;
lazylen[rt] = 1;
if(l==r){
pos[rt] = 1;
return;
}
int mid = l+r>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
void Update(int l,int r,ll d,int L=1,int R=n,int rt=1){
if(L>=l && R<=r){
sum[rt] = (d*pos[rt]*10%mod+(R-L+1)*d%mod + 10*sum[rt]) %mod;
pos[rt] = pos[rt]*100%mod;
lazy1[rt] = (d*lazylen[rt]%mod + lazy1[rt]) %mod;
lazylen[rt] = lazylen[rt]*10%mod;
lazy2[rt] = (lazy2[rt]*10+d)%mod;
pushdown(rt,L,R);
return;
}
pushdown(rt,L,R);
int mid = L+R>>1;
if(l<=mid){
Update(l,r,d,L,mid,rt<<1);
}
if(r>mid){
Update(l,r,d,mid+1,R,rt<<1|1);
}
pushup(rt);
}
ll query(int l,int r,int L=1,int R=n,int rt=1){
if(L>=l && R<=r){
return sum[rt];
}
pushdown(rt,L,R);
int mid = L+R>>1;
ll ans = 0;
if(l<=mid){
ans = (ans + query(l,r,L,mid,rt<<1))%mod;
}
if(r>mid){
ans = (ans + query(l,r,mid+1,R,rt<<1|1))%mod;
}
return ans;
}
int Sheryang(){
int T=read;
for(int Case=1 ; Case<=T ; Case++){
n=read;
int Q=read;
build();
printf("Case %d: \n",Case);
while(Q--){
char s[10];
scanf("%s",s);
if(s[0]=='w'){
int l=read,r=read,val=read;
Update(l,r,val);
}else{
int l=read,r=read;
printf("%lld\n",query(l,r));
}
}
}
return 0;
}