噩梦场。

题目出奇的难,好像一群外国老哥看 A 看着看着就哭了……


A

找到 \(b\) 最低的 \(1\),这个 \(1\) 肯定要跟 A 中的一个 \(1\) 搭配,而且是能搭配的 \(1\) 中最低的。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=100010,mod=998244353;
#define MP make_pair
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
int x=0,f=0;char ch=getchar();
while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return f?-x:x;
}
int t,n,m;
char a[maxn],b[maxn];
int main(){
t=read();
while(t--){
scanf("%s",a+1);scanf("%s",b+1);
n=strlen(a+1);m=strlen(b+1);
int at,ans=0;
ROF(i,m,1) if(b[i]=='1'){at=n-(m-i);break;}
while(at>0 && a[at]=='0') at--,ans++;
printf("%d\n",ans);
}
}

B

大力枚举 \(i,j\)。对于每个 \(i,j\) 都 \(O(n)\) 算,每次就是问在相邻两个数之间最少加多少个数。特别注意相邻两个数相同的情况。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=2000200,mod=998244353;
#define MP make_pair
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
int x=0,f=0;char ch=getchar();
while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return f?-x:x;
}
int n,ok[10][10][111],okk[10][10][10];
char s[maxn];
int main(){
scanf("%s",s+1);
n=strlen(s+1);
MEM(ok,0x3f);MEM(okk,0x3f);
FOR(i,0,9) FOR(j,0,9){
ok[i][j][0]=0;
FOR(l,0,99){
ok[i][j][l+i]=min(ok[i][j][l+i],ok[i][j][l]+1);
ok[i][j][l+j]=min(ok[i][j][l+j],ok[i][j][l]+1);
}
FOR(k,1,110) okk[i][j][k%10]=min(okk[i][j][k%10],ok[i][j][k]);
if(!i || !j) okk[i][j][0]=1;
// FOR(k,0,9) printf("ok[%d][%d][%d]=%d\n",i,j,k,ok[i][j][k]);
}
FOR(i,0,9){
FOR(j,0,9){
int ans=0;
bool flag=true;
FOR(k,2,n){
int x=okk[i][j][(s[k]-s[k-1]+10)%10];
x=max(x-1,0);
if(x>=1e9){printf("-1 ");flag=false;break;}
ans+=x;
}
if(flag) printf("%d ",ans);
}
puts("");
}
}

C

毒瘤玩意……当然可能是我写复杂了。

上下和左右互不干扰,分开考虑。以上下为例。

把上看成 \(1\),下看成 \(-1\),那么竖直方向一共跨过了最大前缀和-最小前缀和单位。

不妨枚举在哪里插入字符,然后瞎合并一通。

需要很多东西,比如每个前缀的后缀和的后缀最大值。(smg……)

不保证代码能让大家都理解。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=200020,mod=998244353;
#define MP make_pair
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
int x=0,f=0;char ch=getchar();
while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return f?-x:x;
}
int t,n,n1,n2,pre1[maxn],suf1[maxn],pre2[maxn],suf2[maxn];
int mnpre1[maxn],mxpre1[maxn],mnpre2[maxn],mxpre2[maxn],mnsuf1[maxn],mxsuf1[maxn],mnsuf2[maxn],mxsuf2[maxn];
int s1[maxn],s2[maxn];
ll ans;
char s[maxn];
void calc(int n,int a[],int pre[],int suf[],int mnpre[],int mxpre[],int mnsuf[],int mxsuf[]){
FOR(i,1,n) pre[i]=pre[i-1]+a[i];
ROF(i,n,1) suf[i]=suf[i+1]+a[i];
FOR(i,1,n) mnpre[i]=a[i]+min(0,mnpre[i-1]),mxpre[i]=a[i]+max(0,mxpre[i-1]);
ROF(i,n,1) mnsuf[i]=min(mnsuf[i+1],suf[i]),mxsuf[i]=max(mxsuf[i+1],suf[i]);
// FOR(i,1,n) printf("pre[%d]=%d,suf[%d]=%d,mnpre[%d]=%d,mxpre[%d]=%d,mnsuf[%d]=%d,mxsuf[%d]=%d\n",i,pre[i],i,suf[i],i,mnpre[i],i,mxpre[i],i,mnsuf[i],i,mxsuf[i]);
}
int main(){
t=read();
while(t--){
scanf("%s",s+1);
n=strlen(s+1);
n1=n2=0;
FOR(i,1,n){
if(s[i]=='W') s1[++n1]=1;
else if(s[i]=='S') s1[++n1]=-1;
else if(s[i]=='A') s2[++n2]=1;
else s2[++n2]=-1;
}
calc(n1,s1,pre1,suf1,mnpre1,mxpre1,mnsuf1,mxsuf1);
calc(n2,s2,pre2,suf2,mnpre2,mxpre2,mnsuf2,mxsuf2);
ans=1ll*(mxsuf2[1]-mnsuf2[1]+1)*(mxsuf1[1]-mnsuf1[1]+1);
// cout<<ans<<endl;
FOR(i,0,n1) ans=min(ans,1ll*(mxsuf2[1]-mnsuf2[1]+1)*(
min(
max(mxsuf1[i+1],suf1[i+1]+1+max(mxpre1[i],0))-min(mnsuf1[i+1],suf1[i+1]+1+min(mnpre1[i],0)),
max(mxsuf1[i+1],suf1[i+1]-1+max(mxpre1[i],0))-min(mnsuf1[i+1],suf1[i+1]-1+min(mnpre1[i],0))
)+1));
// cout<<ans<<endl;
FOR(i,0,n2) ans=min(ans,1ll*(mxsuf1[1]-mnsuf1[1]+1)*(
min(
max(mxsuf2[i+1],suf2[i+1]+1+max(mxpre2[i],0))-min(mnsuf2[i+1],suf2[i+1]+1+min(mnpre2[i],0)),
max(mxsuf2[i+1],suf2[i+1]-1+max(mxpre2[i],0))-min(mnsuf2[i+1],suf2[i+1]-1+min(mnpre2[i],0))
)+1));
cout<<ans<<endl;
FOR(i,0,n+1) pre1[i]=suf1[i]=pre2[i]=suf2[i]=mxpre1[i]=mnpre1[i]=mxsuf1[i]=mnsuf1[i]=mxpre2[i]=mnpre2[i]=mxsuf2[i]=mnsuf2[i]=0;
}
}

D

考虑只有一个 \(7\) 能不能做。\(7\) 明显在最右边。对于每个 \(1\),求出它右边有 \(x_i\) 个 \(3\),答案就是 \(\sum\frac{x_i(x_i-1)}{2}\)。

然后每次选一个尽可能大的 \(x_i\),不停构造,由于 \(x_i\) 肯定不超过 \(50000\),而且无论 \(n\) 多小都可以在后面加 \(2\) 个 \(3\) 使得 \(n\) 减少 \(1\),所以这组解一定存在且合法。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=100010,mod=998244353;
#define MP make_pair
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
int x=0,f=0;char ch=getchar();
while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return f?-x:x;
}
int t,n,a[maxn],k;
int main(){
t=read();
while(t--){
n=read();k=0;MEM(a,0);
while(n){
a[++k]=sqrt(2*n);
while(a[k]*(a[k]-1)<=2*n) a[k]++;
while(a[k]*(a[k]-1)>2*n) a[k]--;
n-=a[k]*(a[k]-1)/2;
}
FOR(i,1,k){
printf("1");
FOR(j,1,a[i]-a[i+1]) printf("3");
}
printf("7\n");
}
}

E

最小清新的一道题。

考虑求出 \(a[i]\) 表示在 \(t\) 中能以 \(i\) 结尾匹配的串的个数,\(b[i]\) 表示在 \(t\) 中能以 \(i\) 开头匹配的串的个数。答案是 \(\sum a[i]b[i+1]\)。

这两个东西都可以通过 AC 自动机简单求。大概就是维护 fail 链上末尾节点的个数之类的。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=200020,mod=998244353;
#define MP make_pair
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
int x=0,f=0;char ch=getchar();
while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return f?-x:x;
}
struct ACAM{
int cnt,ch[maxn][26],fail[maxn],q[maxn],sum[maxn],h,r,val[maxn];
void insert(char *s,int l){
int now=0;
FOR(i,1,l){
int p=s[i]-'a';
if(!ch[now][p]) ch[now][p]=++cnt;
now=ch[now][p];
}
sum[now]++;
}
void build(){
h=1;r=0;
FOR(i,0,25) if(ch[0][i]) q[++r]=ch[0][i];
while(h<=r){
int u=q[h++];
FOR(i,0,25) if(ch[u][i]){
fail[ch[u][i]]=ch[fail[u]][i];
sum[ch[u][i]]+=sum[fail[ch[u][i]]];
q[++r]=ch[u][i];
}
else ch[u][i]=ch[fail[u]][i];
}
}
void run(char *s,int l){
int now=0;
FOR(i,1,l){
int p=s[i]-'a';
now=ch[now][p];
val[i]=sum[now];
}
}
}AC[2];
int n,l;
ll ans;
char t[maxn],s[maxn];
int main(){
scanf("%s",t+1);l=strlen(t+1);
n=read();
FOR(i,1,n){
scanf("%s",s+1);
int len=strlen(s+1);
AC[0].insert(s,len);
for(int j=1,k=len;j<k;j++,k--) swap(s[j],s[k]);
AC[1].insert(s,len);
}
AC[0].build();AC[1].build();
AC[0].run(t,l);
for(int i=1,j=l;i<j;i++,j--) swap(t[i],t[j]);
AC[1].run(t,l);
FOR(i,1,l) ans+=1ll*AC[0].val[i]*AC[1].val[l-i];
// FOR(i,1,l) printf("val1[%d]=%d,val2[%d]=%d\n",i,AC[0].val[i],i,AC[1].val[l-i+1]);
cout<<ans<<endl;
}

Educational Codeforces Round 70 题解的更多相关文章

  1. Educational Codeforces Round 70 (Rated for Div. 2) 题解

    比赛链接:https://codeforc.es/contest/1202 A. You Are Given Two Binary Strings... 题意:给出两个二进制数\(f(x)\)和\(f ...

  2. Educational Codeforces Round 19 题解【ABCDE】

    A. k-Factorization 题意:给你一个n,问你这个数能否分割成k个大于1的数的乘积. 题解:因为n的取值范围很小,所以感觉dfs应该不会有很多种可能-- #include<bits ...

  3. Educational Codeforces Round 55 题解

    题解 CF1082A [Vasya and Book] 史上最难A题,没有之一 从题意可以看出,翻到目标页只有三种办法 先从\(x\)到\(1\),再从\(1\)到\(y\) 先从\(x\)到\(n\ ...

  4. Codeforces Educational Codeforces Round 54 题解

    题目链接:https://codeforc.es/contest/1076 A. Minimizing the String 题意:给出一个字符串,最多删掉一个字母,输出操作后字典序最小的字符串. 题 ...

  5. Codeforces Educational Codeforces Round 57 题解

    传送门 Div 2的比赛,前四题还有那么多人过,应该是SB题,就不讲了. 这场比赛一堆计数题,很舒服.(虽然我没打) E. The Top Scorer 其实这题也不难,不知道为什么这么少人过. 考虑 ...

  6. Educational Codeforces Round 57题解

    A.Find Divisible 沙比题 显然l和2*l可以直接满足条件. 代码 #include<iostream> #include<cctype> #include< ...

  7. Educational Codeforces Round 24 题解

    A: 考你会不会除法 //By SiriusRen #include <bits/stdc++.h> using namespace std; #define int long long ...

  8. Educational Codeforces Round 70 (Rated for Div. 2)

    这次真的好难...... 我这个绿名蒟蒻真的要崩溃了555... 我第二题就不会写...... 暴力搜索MLE得飞起. 好像用到最短路?然而我并没有学过,看来这个知识点又要学. 后面的题目赛中都没看, ...

  9. Educational Codeforces Round 70

    目录 Contest Info Solutions A. You Are Given Two Binary Strings... B. You Are Given a Decimal String.. ...

随机推荐

  1. 大话设计模式Python实现-备忘录模式

    备忘录模式(Memento Pattern):不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,这样已经后就可将该对象恢复到原先保存的状态 下面是一个备忘录模式的demo: #! ...

  2. MyBatis 获取插入记录的 id

    现在的项目改用 Guns 了,也是一个很不错的框架,用起来也感觉很不错,上手也挺方便的.毕竟对于只是应用层面的知识,也基本上就是看看手册,熟悉熟悉就可以轻松上手了.如果是想要深入,或者刨根问底,那么就 ...

  3. 快速入门:Python简单实例100个(入门完整版)

    Python3 100例 文章目录 Python3 100例 实例001:数字组合 实例002:“个税计算” 实例003:完全平方数 实例004:这天第几天 实例005:三数排序 实例006:斐波那契 ...

  4. vuex 源码解析(四) mutation 详解

    mutation是更改Vuex的store中的状态的唯一方法,mutation类似于事件注册,每个mutation都可以带两个参数,如下: state ;当前命名空间对应的state payload ...

  5. Spring源码系列 — 构造和初始化上下文

    探索spring源码实现,精华的设计模式,各种jdk提供的陌生api,还有那么点黑科技都是一直以来想做的一件事!但是读源码是一件非常痛苦的事情,需要有很大的耐心和扎实的基础. 在曾经读两次失败的基础上 ...

  6. Beats Elastic中的Auditbeat使用介绍

    Auditbeat使用介绍 Auditbeat是一种轻量级的数据收集器,您可以将其安装在服务器上,以审核系统上用户和进程的活动. 例如,您可以使用Auditbeat从Linux Audit Frame ...

  7. 使用IDEA的Git插件上传项目教程

    如何使用IDEA的Git插件上传项目 一.在https://www.cnblogs.com/zyx110/p/10799387.html中下载 二.注册码云账号 搜索gitee码云插件并安装

  8. Python-函数参数类型及排序问题

    Python中函数的参数问题有点复杂,主要是因为参数类型问题导致的情况比较多,下面来分析一下. 参数类型:缺省参数,关键字参数,不定长位置参数,不定长关键字参数. 其实总共可以分为    位置参数和关 ...

  9. addEventListener和JavaScript的事件机制

    JavaScript的事件处理分为两个阶段: 捕获阶段:从根节点向event.target层层传递 冒泡阶段:从event.target向根节点层层传递 addEventListener(eventN ...

  10. delphi FillChar的用法(转)

    delphi FillChar的用法(转) (2012-12-24 15:12:06) 转载▼ 标签: it 分类: delphi7 FillChar的用法(delphi) Fillchar是Turb ...