题目
题目大意
给出一个操作序列,询问给出一个区间,
求这个区间操作所产生的答案。
题解
假设先对原操作序列求一次答案,
那么询问的某个区间的答案就一定是连续的一段。
有了这个想法,这题就很简单了。
首先先在操作序列的最前端添加一定数量的”>”保证指针不会从左边出去,
维护0-9的前缀和,已经每一个位置第一次被左边的位置的时刻
fi
f
i
以及第一次被右边的位置到达的时刻
gi
g
i
用链表来处理删除一个字符。
维护
gi
g
i
的时候要注意这个字符可能已经被删去。
有了这些信息,对于一次查询l,r,
那么进入这个区间的时刻就是
fi
f
i
离开这个区间的时刻就是min(
gl,fr+1
g
l
,
f
r
+
1
)
用前缀和减一下就是答案了。
code
#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <vector>
#define ll long long
#define N 200003
#define M 103
#define db double
#define P putchar
#define G getchar
#define inf 998244353
#define pi 3.1415926535897932384626433832795
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
ll abs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}
char s[N];
int pre[N],nxt[N],d[N*10],n,m,f[N],g[N];
int x,y,tot,p1,p2,id,lst;
int S[10][N*5],z[N],top;
void del(int x)
{
nxt[pre[x]]=nxt[x];
pre[nxt[x]]=pre[x];
}
int main()
{
freopen("program2.in","r",stdin);
freopen("program.out","w",stdout);
read(n);read(m);
for(ch=G();(ch<'0' || ch>'9') && ch!='<' && ch!='>';ch=G());
nxt[0]=1;
for(int i=1;i<=n;i++)
{
s[i]=ch;ch=G();
pre[i]=i-1;nxt[i]=i+1;
if(s[i]=='<')
{
tot++;
s[n+tot]='>';
pre[nxt[n+tot]=nxt[0]]=n+tot;
nxt[0]=n+tot;
}
}
nxt[n]=n+tot+1;id=1;
for(x=1,y=0;x && x!=n+tot+1;lst=x,x=p2)
{
p1=pre[x];p2=nxt[x];
if(y)
{
swap(p1,p2);
while((z[top]>x || x>n) && top)g[z[top--]]=id;
}else
{
if(!g[x] && x<=n)z[++top]=x;
if(x<=n && !f[x])f[x]=id;
}
if(s[x]=='<' || s[x]=='>')
{
if(s[lst]=='<' || s[lst]=='>')del(lst);
if(s[x]=='>')y=0;else y=1;
p1=pre[x];p2=nxt[x];
if(y)swap(p1,p2);
}
else
{
id++;
for(int i=0;i<=9;i++)
S[i][id]=S[i][id-1];
S[s[x]-48][id]++;
if(s[x]==48)del(x);
s[x]--;
}
}
for(int i=1;i<=m;i++)
{
read(p1);read(p2);
x=f[p1];y=min(g[p1]?g[p1]:id,f[p2+1]?:id);
for(int j=0;j<=9;j++)
write(S[j][y]-S[j][x]),P(' ');
P('\n');
}
return 0;
}