欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[雅礼集训]program(鬼知道原题叫什么名字。。。)

程序员文章站 2022-06-03 13:22:11
...

题面:
[雅礼集训]program(鬼知道原题叫什么名字。。。)

恩。。。部分分比正解难系列。。。目前还是没写出所有询问的r=n的部分。分类讨论太麻烦了。。。

还是说正解:
[雅礼集训]program(鬼知道原题叫什么名字。。。)

恩我就是这么懒。。。感觉这一部分讲得肯定比我自己描述清楚;

不过中间有个很重要的细节,由于当一个点为0时,如果立即将其删除,可能他的g[]数组就不会被标记上;
这时候就要延时删除一下;
同时判断一个”<”或”>”是否要删时就需要跳过中间正在被延时删除的点。。。

细节看代码或者自己去实现。。。我这代码直接魔改的暴力,我自己看着都头疼。。。

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
const int maxn=100005;
const int inf=1000000007;
int n,t;
char s[maxn],a[maxn];
struct ANSWER{
    int v[10];
    void clear(){
        for(int i=0;i<10;i++)v[i]=0;
    }
    ANSWER operator -(const ANSWER &b){
        ANSWER c;
        c.clear();
        for(int i=0;i<10;i++)c.v[i]=v[i]-b.v[i];
        return c;
    }
}ans[maxn*10];
void write(ANSWER a){
    for(int i=0;i<10;i++)printf("%d ",a.v[i]);
    printf("\n");
}
int next[maxn],front[maxn];
int f[maxn],g[maxn];
void findanslow()
{
        for(int i=1;i<=n;i++)f[i]=g[i]=inf;
        for(int k=1;k<=n;k++)a[k]=s[k];
        for(int k=1;k<=n;k++)next[k]=k+1,front[k]=k-1;
        a[0]='>';
        a[n+1]='>';
        front[1]=0;
        next[0]=1;
        next[n]=0;
        bool flag=true;
        ans[0].clear();
        int tl=0;
        for(int i=1;!(i==0&&flag);i= flag ? next[i]:front[i]){
            tl++;
            ans[tl]=ans[tl-1];
            if(flag==true)f[i]=std::min(tl-1,f[i]);
            if(isdigit(a[i])){
                ans[tl].v[a[i]-'0']++;
                a[i]--;
            }
            else if(a[i]=='>'){
                flag=true;
                if(!i)continue;
                int pos;
                for( pos=next[i];a[pos]<'0';pos=next[pos]);
                if(a[pos]=='>'||a[pos]=='<')a[i]='0'-1;
            }
            else if(a[i]=='<'){
                flag=false;
                int pos;
                for( pos=front[i];a[pos]<'0';pos=front[pos]);
                if(a[pos]=='>'||a[pos]=='<')a[i]='0'-1;
            }else a[i]--;
            if(flag==false)
            {

                for(int k=front[i]+1;k<=i;k++)
                g[i]=std::min(g[i],tl);
            }
            if(a[i]<'0'-1)next[front[i]]=next[i],front[next[i]]=front[i];
        }
        f[n+1]=tl;
}
int main()
{
    freopen("program.in","r",stdin);
    freopen("program.out","w",stdout);
    scanf("%d%d",&n,&t);
    scanf("%s",s+1);
    findanslow();
    ANSWER zero;
    zero.clear();
    for(int i=1;i<=t;i++){
        int tl,tr;
        scanf("%d%d",&tl,&tr);
        int l=f[tl];
        int r=std::min(g[tl],f[tr+1]);
        if(l==inf||r==inf)write(zero);
        else write(ans[r]-ans[l]);
    }
    return 0;
}
相关标签: oi