• 洛谷 P5640 【CSGRound2】逐梦者的初心


    洛谷 P5640 【CSGRound2】逐梦者的初心

    洛谷传送门

    题目背景

    注意:本题时限修改至250ms,并且数据进行大幅度加强。本题强制开启O2优化,并且不再重测,请大家自己重新提交。

    由于Y校的老师非常毒瘤,要求zhouwc在csp考前最后3天参加期中考,zhouwc非常生气,决定消极考试,以涂完卡但全错为目标。现在retcarizy看zhouwc太可怜了,想要帮zhouwc解决一个问题,但他自己又太忙了,咕咕咕,于是就把问题甩给了你。

    题目描述

    给你一个长度为n的字符串S。

    有m个操作,保证mle nmn

    你还有一个字符串T,刚开始为空。

    共有两种操作。

    第一种操作:

    在字符串T的末尾加上一个字符。

    第二种操作:

    在字符串T的开头加上一个字符。

    每次操作完成后要求输出有几个l in [1,T.size]l∈[1,T.siz**e]满足以下条件:

    对于forall i in [1,l]∀i∈[1,l]有T_{T.size-l+i} e S_{i}T**T.siz**el+i=S**i

    Tip:Tip:字符串下标从1开始。T.sizeT.siz**e表示T的长度。

    输入格式

    第一行两个正整数n,mn,m

    第二行n个正整数,用空格隔开,第ii个整数表示S_iS**i

    接下来mm行,每行两个数字opt,chopt,c**h,opt=0opt=0表示在T的末尾加一个字符chc**h,opt=1opt=1表示在T的开头加一个字符chc**h

    输出格式

    共mm行,每行一个非负整数表示第m操作后的输出。


    题解:

    很久之前打的模拟赛,今天刷状压重新刷到了这个。了债可。

    记得当时打的70分做法,使用了双端队列。其实STL真是个好东西,能够比较简便地维护很多我们本需要手打大数据结构来维护的东西。打暴力程序的时候用它们也有很奇迹的效果。建议多学学。

    时隔太久,有点忘记了双端队列的做法,但是思路就是大力模拟,应该很容易看懂。就直接放代码了。

    70pts代码:

    #include<cstdio>
    #include<deque>
    #include<vector>
    using namespace std;
    const int maxn=1e6+10;
    int n,m;
    int s[maxn];
    bool flag;
    char *p1,*p2,buf[100000];
    #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
    int read()
    {
        int x=0,f=1;
        char ch=nc();
        while(ch<48){if(ch=='-')f=-1;ch=nc();}
        while(ch>47)    x=(((x<<2)+x)<<1)+ch-48,ch=nc();
        return x*f;
    }
    deque<int> q;
    vector<int> vec;
    vector<int>::iterator it;
    int main()
    {
        n=read();m=read();
        for(int i=0;i<n;i++)
            s[i]=read();
        while(m--)
        {
            int opt=read();
            int x=read();
            if(opt)
            {
                q.push_front(x);
                flag=0;
                for(int i=0;i<q.size();i++)
                    if(q[i]==s[i])
                    {
                        flag=1;
                        break;
                    }
                if(!flag)
                    vec.push_back(q.size());
            }
            else
            {
                q.push_back(x);
                it=vec.begin();
                while(it!=vec.end())
                {
                    (*it)++;
                    if(s[*it-1]==x)
                        vec.erase(it);
                    else    
                        ++it;
                }
                if(s[0]!=x)
                    vec.push_back(1);
            }
            printf("%d
    ",vec.size());
        }
        return 0;
    }
    

    然后考虑满分思路:

    由于每个位置和每种字符都是独立的,对每种字符都记录一下位子。怎么记录呢?用(f[i]=0/1)表示长度为i的后缀可不可以,0表示可以,1表示不行。

    于是bitset优化就比较明显了。

    你看,又是bitset

    在末尾加一个字符时,左移后做or运算。

    在开头加一个字符时,直接or上该字符出现的状态左移长度减一位。

    答案就是范围内0的个数。

    满分代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+10;
    int n,m,opt,s[maxn],dt;
    bitset<35005> dp,id[1005],now;
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&s[i]);
    	for(int i=1;i<=m;i++)
    		id[s[i]].set(i);
    	now.set();
    	for(int i=1;i<=m;i++)
        {
    		scanf("%d%d",&opt,&dt);
    		now.reset(i);
    		if(opt==0)
    			dp=(dp<<1)|id[dt];
    		else
    			dp=dp|(id[dt]<<(i-1));
    		printf("%d
    ",(~(dp|now)).count());
    	}
    	return 0;
    }
    
  • 相关阅读:
    泛型接口与NUnit初试
    异步文件IO的应用
    [Andrew McAfee]Enterprise 2.0下的大趋势
    silverlight
    扩展prototype库兼容w3c domajax for firefox
    开张了
    最长平台
    常见C/C++ XML解析器比较
    GIS地图开发
    几种常见 容器 比较和分析 hashmap, map, vector, list ...hash table
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13804585.html
Copyright © 2020-2023  润新知