Автор проблеми: | Псюк Юрій |
Підготовлено: | Псюк Юрій та Андрій Холод |
Розбір: | Псюк Юрій |
Рішення
Будемо вирішувати офлайн окремо для кожної пари та . Використаємо метод . Коли розглядатимемо усі запити, що лежать на відрізку від до , з цетром , то щоб порахувати відповідь для запита, що проходить через сердину, підрахуємо масив , що буде підтримувати ( [s_i , s_m],,) для ,а для m+1 буде тримати ( [s_{m+1} , s_R],,). Залишилось додати від рядків, що проходять через центр.
Складність становить \mathcal{O}((n+q)*log(n))
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pll;
typedef pair<pll,ll> ppl;
ll ans[300009],a[300009],n,prs[300009],prcnt[300009],ds[300009],mod,psdes[300009],stdes[300009],number1,number2;
bool is(ll x){
return (x==number1 || x==number2);
}
void dcq(ll L,ll R,vector<ppl> C){
if(L>R || C.size()==0) return;
if(L==R) {
for(auto x:C) ans[x.second]=is(a[L])*a[L];
return;
}
ll m=(L+R)>>1;
ds[m]=is(a[m])*a[m];
prs[m]=is(a[m])*a[m];
prcnt[m]=is(a[m]);
ll k=is(a[m])+1; ll s=ds[m]; ll ma=s;
for(int i=m-1;i>=L;i--){
ds[i]=ds[i+1];
if(is(a[i])){
ds[i]=(ds[i]+psdes[k]*a[i]+s)%mod;
ma=(ma+stdes[k-1]*a[i])%mod;
s=(s+psdes[k]*a[i])%mod;
k++;
}
else{
k=1;
s=0;
ma=0;
}
if(k==m-i+2) {
prcnt[i]=prcnt[i+1]+1;
prs[i]=(prs[i+1]+ma)%mod;
}
else{
prcnt[i]=prcnt[i+1];
prs[i]=prs[i+1];
}
}
ds[m+1]=is(a[m+1])*a[m+1];
prs[m+1]=is(a[m+1])*a[m+1];
prcnt[m+1]=is(a[m+1]);
k=is(a[m+1])+1; s=ds[m+1]; ma=s;
for(int i=m+2;i<=R;i++){
ds[i]=ds[i-1];
if(is(a[i])){
ds[i]=(ds[i]+k*a[i]+s*10)%mod;
ma=(ma*10+a[i])%mod;
s=(s*10+a[i]*k)%mod;
k++;
}
else{
k=1;
s=0;
ma=0;
}
if(k==i-m+1) {
prcnt[i]=prcnt[i-1]+1;
prs[i]=(prs[i-1]+ma)%mod;
}
else{
prcnt[i]=prcnt[i-1];
prs[i]=prs[i-1];
}
}
vector<ppl> AL,AR;
for(auto x:C) {
if(x.first.second==m) ans[x.second]=ds[x.first.first];
else if(x.first.first==m+1) ans[x.second]=ds[x.first.second];
else if(x.first.second<m) AL.push_back(x);
else if(x.first.first>m+1) AR.push_back(x);
else{
ans[x.second]=(ds[x.first.first]+ds[x.first.second]+(prs[x.first.second]*prcnt[x.first.first]+prs[x.first.first]*psdes[prcnt[x.first.second]]%mod*10))%mod;
}
}
dcq(L,m-1,AL);
dcq(m+2,R,AR);
}
void solve(){
mod=998244353;
stdes[0]=1;
for(int i=1;i<=3e5;i++) stdes[i]=stdes[i-1]*10%mod;
for(int i=1;i<=3e5;i++) psdes[i]=(psdes[i-1]+stdes[i-1])%mod;
vector<ppl> z[11][11];
string s;
cin>>s;
n=s.size();
for(int i=1;i<=n;i++) a[i]=s[i-1]-'0';
ll q,L,R;
cin>>q;
for(int i=1;i<=q;i++) {
ll A,B;
cin>>L>>R>>A>>B;
if(A>B) swap(A,B);
z[A][B].push_back({{L,R},i});
}
for(int A=1;A<=9;A++) for(int B=A;B<=9;B++) {
number1=A;
number2=B;
dcq(1,n,z[A][B]);
}
for(int i=1;i<=q;i++) cout<<ans[i]<<"\n";
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll tt=1;
//cin>>tt;
while(tt--){
solve();
}
return 0;
}