首页 > 其他分享 >9.6 上午 becoder 模拟赛总结&题解

9.6 上午 becoder 模拟赛总结&题解

时间:2024-09-06 12:03:06浏览次数:8  
标签:ch int 题解 scanf 表头 链表 v2 becoder 9.6

T1 语言

水题不多说,很容易发现 NP 需要满足的只是最后一个单词为 N,前面是 A 或 N 都可以随意放。

所以用两个数组,\(v1_i\) 记录以 \(i\) 结尾的前缀是否可以构成 NP,\(v2_i\) 记录以 \(i\) 为开头的后缀是否可以构成 NP。

最后 for 循环扫一遍是否有同时满足 \(v1_{i-1}=true\) 和 \(v2_{i+1}=true\) 的就可以了。

时间复杂度 \(O(n)\),代码如下(100pts):

#include<bits/stdc++.h>
using namespace std;
char ch[100005];
int t,len,flag,w[26],v1[100005],v2[100005];
int main(){
    scanf("%d",&t);
    while(t--){
        for(int i=0;i<26;i++)  scanf("%d",w+i);
        memset(v1,0,sizeof v1);
        memset(v2,0,sizeof v2),flag=0;
        scanf("%s",ch+1),len=strlen(ch+1);
        for(int i=1;i<=len;i++){
            if(!(w[ch[i]-'a']&1)&&!(w[ch[i]-'a']&2))  break;
            if(w[ch[i]-'a']&2)  v1[i]=1;
        }
        if(w[ch[len]-'a']&2){
            for(int i=len;i>0;i--){
                if(!(w[ch[i]-'a']&1)&&!(w[ch[i]-'a']&2))  break;
                v2[i]=1;
            }
        }
        for(int i=2;i<len;i++)  flag|=(v1[i-1]&&v2[i+1]&&(w[ch[i]-'a']&4));
        printf("%s\n",flag?"Yes":"No");
    }
}

T2 色球

很明显的双向链表的题目,但这道题一定不能去想哪边是 \(pre\) 哪边是 \(next\),不然就会把自己给绕进去。

对于链表的每一块,维护 \(col\) 和 \(val\) 两个信息,而对于每个桶,维护里面链表的表头和表尾就行了。

对于操作 1,我们把当前找的这个链表的表头,那边没有值就把那边赋值成现在加进去的这一块。

对于操作 2,如果现在的这个表头的 \(val\) 已经大于等于 \(x\) 了,就直接 break,然后输出表头的 \(col\) 就行了。

否则,因为表头一定只有一边有值,我们直接往那一边跳就行了。

而对于现在跳到的这一个点,哪边是刚才的表头,就直接赋值成 \(0\) 就行了,另外一边就是它下面的数。

对于操作 3,直接把两个表头连起来,然后把 \(v\) 的表头赋值成 \(u\) 的表尾就行了。

代码如下(100pts):

#include<bits/stdc++.h>
using namespace std;
#define N 200005
char op[10];
int n,m,cnt,hed[N],tal[N],col[N],val[N],ch1[N],ch2[N];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1,x,y,z;i<=m;i++){
        scanf("%s%d%d",op,&x,&y);
        if(op[2]=='s'){
            scanf("%d",&z),cnt++;
            if(!tal[z])  tal[z]=cnt;
            col[cnt]=y,val[cnt]=x,ch1[cnt]=hed[z];
            (ch1[hed[z]]?ch2[hed[z]]=cnt:ch1[hed[z]]=cnt),hed[z]=cnt;
        }
        if(op[2]=='p'){
            while(val[hed[y]]<x){
                x-=val[hed[y]];
                int to=(ch1[hed[y]]?ch1[hed[y]]:ch2[hed[y]]);
                (ch1[to]==hed[y]?ch1[to]=0:ch2[to]=0),hed[y]=to;
            }
            val[hed[y]]-=x,printf("%d\n",col[hed[y]]);
        }
        if(op[2]=='t'){
            if(!hed[x])  continue;
            if(!hed[y])  hed[y]=tal[x],tal[y]=hed[x];
            else{
                ch1[hed[y]]?ch2[hed[y]]=hed[x]:ch1[hed[y]]=hed[x];
                ch1[hed[x]]?ch2[hed[x]]=hed[y]:ch1[hed[x]]=hed[y];
                hed[y]=tal[x];
            }
            tal[x]=hed[x]=0;
        }
    }
}

T3 斐波

完全不会,写的 10pts 暴力...

T4 偶数

先写一下 40pts 的做法吧,100pts 的等我过了再来写。

首先,我们把 \(u\) 设成 \(vv\) 的形式,那么扩展后就一定是 \(vwvw\) 的形式.

其中,\(w\) 是 \(v\) 的一个前缀,且是 \(v\) 的周期,这个性质可以手模得出。

而显然的一点,\(w\) 肯定为 \(v\) 的周期中最短的前缀。

那我们就可以通过对 \(v\) 做 kmp 来求出 \(w\),再把 \(vw\) 作为新的 \(v\) 求 \(w\),知道 \(u\) 的长度大于 \(n\)。

最后的询问就可以通过类似字符串 Hash 求解区间 Hash 值的方法,用前缀和来解决了。

时间复杂度 \(O(n+q)\),代码如下(40pts):

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define N 200005
char ch[N];
const LL mod=998244353;
LL t,n,q,po[N],sum[N],Next[N];
int main(){
    scanf("%lld",&t);
    while(t--){
        Next[0]=Next[1]=0,po[0]=1;
        scanf("%s%lld%lld",ch,&n,&q);
        int len=strlen(ch)/2,i=1;
        while(len<n){
            for(;i<len;i++){
                int j=Next[i];
                while(ch[i]!=ch[j]&&j)  j=Next[j];
                Next[i+1]=(j+1)*(ch[i]==ch[j]);
            }
            int tlen=len-Next[len];
            for(int j=0,k=len;j<tlen;j++,k++)  ch[k]=ch[j];
            len+=tlen;
        }
        for(int i=1;i<=n;i++)
            po[i]=po[i-1]*10%mod,sum[i]=(sum[i-1]*10+ch[i-1]-'0')%mod;
        for(int i=1,l,r;i<=q;i++){
            scanf("%d%d",&l,&r);
            printf("%lld\n",(sum[r]-sum[l-1]*po[r-l+1]%mod+mod)%mod);
        }
    }
}

标签:ch,int,题解,scanf,表头,链表,v2,becoder,9.6
From: https://www.cnblogs.com/tkdqmx/p/18399978

相关文章

  • CF381B题解
    我们先理解题意,大致意思是:给你一个序列让你组成一个中间有一个数,左侧递增右侧递减的数列。从这道题的题意来看,大概思路是:1.我们要将最大值设为中间的数,然后左右两端尽可能的小。2.跑两遍循环,分别为左边的递增边的递减。3.还有,因为一个数可以出现很多次,我们需要一个vis......
  • 2024 年高教社杯全国大学生数学建模竞赛B题解题思路(第一版)
    原文链接:https://www.cnblogs.com/qimoxuan/articles/18399372赛题:问题1:抽样检测方案设计分析:抽样检测方案需要在保证决策准确性的同时,尽量减少检测成本。需要考虑抽样误差对决策的影响,以及如何设置抽样大小和接受/拒绝标准。解题思路:1.确定抽样方法:采用属性抽样,......
  • 【洛谷 P1449】后缀表达式 题解(栈+分支)
    后缀表达式题目描述所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。如:对应的后缀表达式为:。在该式中,@为表达式的结束符号。.为操作数的结束符号。输入格式输入一行......
  • CodeForces 2009G Yunli's Subarray Queries 题解
    云璃!高质量Div.4,吊打某些Div.2Only/Edu/Div.3。本题是下面四道题目的有机结合,优雅且经典。LuoguP4168[Violet]蒲公英|LuoguP1997faebdc的烦恼|LuoguP3203[HNOI2010]弹飞绵羊|LuoguP3246[HNOI2016]序列建议先完成这四题。(必须指出:用蒲公英的分块方......
  • P3688 [ZJOI2017] 树状数组 题解
    P3688[ZJOI2017]树状数组题解记录一下做这道题的心路历程,说明在没有事先知道“九条是求成了后缀和”的情况下如何发现,以及解释一些部分分的做法。sub1,18pts:暴力搜索无脑枚举,复杂度\(\mathcalO(n^m)\)。代码:#include<bits/stdc++.h>#defineintlonglong#defineloop......
  • AT_arc151 题解 & 数组字典序大小比较求方案数
    很好的一题,做的时候没有一点思路,看了题解。看来做过的题目还是太少了,记录一下经验。注意到$1\leN\le2\times10^5$和$1\leM\le10^9$,如此庞大的数据,dp是肯定不行的。当字典序$A<B$时,当且仅当存在$i$,使得$\forallx\in[1,i)$,$A_x=B_x$且$A_i<B_i$。那么我们对于$......
  • CF704B Ant Man 题解
    题目传送门前置知识预设性DP解法考虑统计每个数单独的贡献,然后进行预设性DP。设\(f_{i,j}\)表示当前填了\([1,i]\)时有\(j\)个连续段的最小权值,边界为\(f_{0,0}=0\)。对\(i(i\nes,i\nee)\)填入的位置进行分讨。新开一段后面填入的数都比\(i\)大(如果存......
  • 洛谷 P1516 青蛙的约会 题解
    一道简单的数学题~首先分析题意。精简得出:假设跳了\(t\)次,那么青蛙A的坐标是\((x+mt)\modL\),青蛙B的坐标是\((y+nt)\modL\),列出方程:\[x+mt\equivy+nt\pmodL\]由于余数具有可减性,所以把\(y+nt\)移到左边,得出:\[x-y+mt-nt\equiv0\pmodL\]写成人话:\[(x-y+mt-nt)\mod......
  • 9.5 上午 becoder 模拟赛总结 & 题解
    T1文本编辑器说实话,看到题目的第一瞬间,我还以为gm第一道就放了平衡树。一道链表的模板题,当然愿意也可以用平衡树写,不多说了,直接放代码(100pts):#defineN1000005chars[N],t[N];intnow,pre[N],nxt[N];intmain(){scanf("%s%s",s+1,t+1);intn=strlen(s+1);......
  • 【转载】P1399 [NOI2013] 快餐店 题解
    作者%%%%%%NightTide%%%%%%题目大意求一棵基环树的重心。即一个点,使得树上到其距离最长的点到其的距离最短。注意,这个点不一定是一个节点,可以在树上的任意位置。输出树上到其距离最长的点到其的距离。或者说求基环树最短的直径?(大雾解题思路显然,这颗基环树的直径只有两......