[2018雅礼省选集训3-30]program

11人阅读 评论(0) 收藏 举报

注意到程序的运行是连续的,所以假设序列最左端左边还有一个>(且不能删除),那么一个区间子程序运行的过程一定时整个程序运行过程的一个子段。于是只需要用链表模拟一边总程序,再求出子段的开始和结束时间,直接用前缀和减一下即可。
fi表示指针第一次从i1移动到i的时间,gi表示指针第一次从i移动到i1的时间,那么[l,r]对应的子段开始时间就是fl,结束时间就是min(fr+11,gl)
f直接记录即可,但考虑到某些位置还没有从右向左走过就被删除了,会导致某些gi记录不到,我们只要删除i的时候先标记下,等记录过gi之后再真正删去即可。
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200010
using namespace std;
int n,q,b[N],ans[N*10][10],to[2][N],f[N],g[N],tim;
char cs[N];
bool ex[N];
int read()
{
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
int main()
{
    n=read();q=read();
    scanf("%s",cs+1);
    for(int i=1;i<=n;i++)
        if(cs[i]=='<') b[i]=-2;
        else if(cs[i]=='>') b[i]=-1;
        else b[i]=cs[i]-'0';
    b[0]=-1;    
    memset(ans,0,sizeof(ans));
    memset(f,0x3f,sizeof(f));
    memset(g,0x3f,sizeof(g));           
    int v=1,pos=1,lst=1;f[1]=tim=1;

    for(int i=0;i<=n;i++)
        ex[i]=1,to[0][i]=i-1,to[1][i]=i+1;
    to[1][0]=1; 
    while(pos<=n)
    {
        if(ex[pos])
        {
            if(b[pos]>=0) 
            {
                ans[tim][b[pos]]++;
                if(b[pos]>0) b[pos]--;else ex[pos]=0;
            }
            if(b[pos]<0) v=b[pos]+2;
        }

        if(!v) 
        {
            g[pos]=min(g[pos],tim);
            if(!ex[pos]) to[1][to[0][pos]]=to[1][pos],to[0][to[1][pos]]=to[0][pos];
        }
        pos=to[v][pos];

        if(!ex[pos]) continue;
        ++tim;

        memcpy(ans[tim],ans[tim-1],sizeof(ans[tim]));
        if(v) f[pos]=min(f[pos],tim);
        if(lst&&b[lst]<0&&b[pos]<0) ex[lst]=0;  
        lst=pos;
    }
    f[n+1]=tim;
    while(q--)
    {   
        int l=read(),r=read();
        for(int i=0;i<=9;i++)
            printf("%d ",ans[min(f[r+1]-1,g[l])][i]-ans[f[l]-1][i]);
        puts("");
    }
    return 0;
}
查看评论

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

题面: 恩。。。部分分比正解难系列。。。目前还是没写出所有询问的r=n的部分。分类讨论太麻烦了。。。 还是说正解: 恩我就是这么懒。。。感觉这一部分讲得肯定比我自己描述清楚; 不过中间...
  • qq_36284842
  • qq_36284842
  • 2018-03-30 19:07:12
  • 53

雅礼集训1.4 序列

标签:迭代加深搜索,IDA* 题目 序列(sequence) 【题目描述】 给定一个1~n的排列x,每次你可以将x1~xi翻转。你需要求出将序列变为升序的最小操作次数。有多组数据。 【输入数...
  • qwerty1125
  • qwerty1125
  • 2018-01-05 17:43:05
  • 116

[2018雅礼集训1-12]小C的线段树 DP

题面 考虑当n>mn>m时答案为00,1≤nm≤1051\le nm \le 10^5,所以只用考虑n1052n的情况。 把一个区间看成一对括号,设fi,l,rf_{i,l,r}表示前ii个点,之...
  • DOFYPXY
  • DOFYPXY
  • 2018-01-17 22:14:21
  • 160

雅礼集训酱油记(2017-01-11~2017-01-23)

一句话:知道了自己有多弱。。。讲课: 第一天就完全懵逼了,毛爷爷的DP除了学过的听懂了一半,没学过的东西(Knuth、单调性、三分、凸包??)单词都认不到。。。酱油过去。 数据结构还算听懂得比较多...
  • can919
  • can919
  • 2017-01-24 21:59:00
  • 509

雅礼集训Day4

今天炸的1p。。。。。 T1,给你100次询问,每次L,R,选[L,R]中的若干数进行异或,求有多少种结果,1...
  • DraZxlNDdt
  • DraZxlNDdt
  • 2017-06-21 23:49:56
  • 345

[2018雅礼集训1-10]Function 积性函数前缀和

题面 题目要我们求 ∑i=1n∑d|iμ(d)∗σ20(id)\sum_{i=1}^n\sum_{d|i}\mu(d)*\sigma_0^2(\frac{i}{d}) 设f(i)=∑d|iμ(d...
  • DOFYPXY
  • DOFYPXY
  • 2018-01-11 22:18:08
  • 165

[2018雅礼集训1-16]序列 爆搜+贪心

题面 首先问题转化为选取一个(Mi,Vi)(M_i,V_i)的集合,该集合必须满足若Mk|lcm{Mi}M_k|lcm\{M_i\},(Mk,Vk)(M_k,V_k)必须在集合中,最大化∑Vi\su...
  • DOFYPXY
  • DOFYPXY
  • 2018-01-18 20:51:14
  • 99

[2018雅礼集训1-20]B 分块

题面 考虑把序列分成N−−√\sqrt N块,记cnti,jcnt_{i,j}表示第ii块颜色jj的个数,设si,js_{i,j}为i,ji,j两块之间产生的贡献,通过cntcnt可以O(N−−√)...
  • DOFYPXY
  • DOFYPXY
  • 2018-01-20 20:34:31
  • 127

雅礼集训及WC2018划水记

雅礼集训1.30~2.3 noip考成250,没得去thuwc和pkuwc,和czy等去参加本来只有samjia和栋栋的集训队模拟。抱着被虐的心态去比赛。 第一天刚到比较困,比赛有点没精神,看到t...
  • ZLTJohn
  • ZLTJohn
  • 2018-02-12 22:25:15
  • 150
    个人资料
    持之以恒
    等级:
    访问量: 2万+
    积分: 2407
    排名: 1万+
    最新评论