8.19考试总结(NOIP模拟44)[Emotional Flutter·Medium Counting·Huge Counting·字符消除2 ]
在自称善意的之时,即存恶意。
前言
几乎是大暑假的最后一次考试了。
我也迎来了我的第一次报零(雾
T1 Emotional Flutter
解题思路
比较考验思维能力,其实就是区间覆盖问题。
我考场上是想到了一个 dfs 实现区间覆盖的做法(手动实现线段树???)。
查找最后剩下的没有被黑条覆盖的长度是否大于脚长。
只可惜最后写了半天的代码手动模拟了十余组样例,最后时空双爆(裂开。
正解思路有一些变化,把每一个黑条的长度增加脚长的长度,白条减去。
然后直接查询是否有空隙就好了,把每一个黑条的左右边界 \(\bmod\) 一下步长。
如果取 \(\bmod\) 之后 \(R>L\) 的话就把这个黑条劈成两半,放在两端。
代码实现需要卡一下边界
code
50ptsdfs
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=5e5+10;
int T,n,m,len,s[N],pre[N];
bool flag;
void dfs(int L,int R)
{
if(flag||R<L||R-L+1<len) return ;
if(L-m<=0||R-m<=0)
{
if(L-m<=0&&R-m<=0&&R-L+1>=len) flag=true;
if(L-m<=0&&R-m>0&&0-L+m+1>=len) flag=true;
if(R-m<=0) return ;
}
int p1=upper_bound(pre+1,pre+n+1,L-m)-pre-1;
int p2=lower_bound(pre+1,pre+n+1,R-m)-pre;
if(p1>p2) return ;
if(!p1)
{
dfs(L,0);
L=max(L,pre[1]+1);
p1++;
}
for(int i=p1;i<=p2;i++)
if(!(i&1))
dfs(max(L-m,pre[i-1]+1),min(R-m,pre[i]));
}
void solve()
{
memset(pre,0,sizeof(pre));
len=read(); m=read(); n=read();
flag=false;
for(int i=1;i<=n;i++)
s[i]=read();
for(int i=1;i<=n;i++)
if(s[i]>=m&&(i&1)){printf("NIE\n");return;}
for(int i=1;i<=n;i++)
pre[i]=pre[i-1]+(s[i]%m==0?m:s[i]%m);
dfs(pre[n]+1,pre[n]+m);
if(flag) printf("TAK\n");
else printf("NIE\n");
}
signed main()
{
T=read();
while(T--) solve();
return 0;
}
正解
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=5e5+10;
int T,len,tot,cnt,m,n,pre,s[N];
bool flag;
struct Node
{
int l,r;
bool friend operator < (Node x,Node y)
{
if(x.l==y.l) return x.r>y.r;
return x.l<y.l;
}
}p[N<<1];
void add(int &x,int y,int mod){x+=y;if(x>=mod)x-=mod;}
void solve()
{
len=read(); m=read(); n=read();
pre=tot=cnt=0; flag=false;
for(int i=1;i<=n;i++)
s[i]=read();
for(int i=1;i<=n;i++)
if(s[i]+len>m&&(i&1)){printf("NIE\n");return;}
if(len>=m){printf("NIF");return;}
for(int i=1;i<=n;i++)
{
if(i&1)
{
s[i]+=len; s[i+1]-=len;
int L=(pre+1)%m,R=(pre+s[i]-1)%m;
if(L<=R){p[++tot]=(Node){L,R};goto V;}
p[++tot]=(Node){L,m-1};
p[++tot]=(Node){0,R};
}
V:; add(pre,s[i],m);
}
sort(p+1,p+tot+1); p[++cnt]=p[1];
for(int i=2;i<=tot;i++)
if(p[i].l<p[cnt].l||p[i].r>p[cnt].r)
p[++cnt]=p[i];
if(p[1].l>0||p[cnt].r<m-1) flag=true;
for(int i=1;i<cnt&&!flag;i++)
flag|=(p[i].r+1<p[i+1].l);
if(flag) printf("TAK\n");
else printf("NIE\n");
}
signed main()
{
T=read();
while(T--) solve();
return 0;
}
T2 Medium Counting
解题思路
又是 数位 DP
\(f_{l,r,pos,ch}\)表示考虑 \([l,r]\) 的字符串的 pos 之前的位置至少填 ch 的方案数
转移分为两种:
考虑由更大的 ch 转移 \(f_{l,r,pos,ch+1}\)
枚举分界点 \(mid\in[l,r]\) 令 \(S_l \sim S_{mid}\) 的 pos 位都是 ch,
可以由\(f_{l,mid,pos,0}\times f_{mid+1,r,pos+1,ch}\)转移
剩下的就是用dfs实现数位 DP 了。
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=60,M=30,mod=990804011;
int n,Len,s[N][M],f[N][N][M][M];
char ch[M];
void add(int &x,int y){x+=y;if(x>mod)x-=mod;}
int dfs(int l,int r,int pos,int cha)
{
if(~f[l][r][pos][cha]) return f[l][r][pos][cha];
if(l>r) return f[l][r][pos][cha]=1;
if(pos>Len) return f[l][r][pos][cha]=(l==r);
if(cha>26) return f[l][r][pos][cha]=0;
f[l][r][pos][cha]=dfs(l,r,pos,cha+1);
for(int mid=l;mid<=r&&(s[mid][pos]==cha||(s[mid][pos]==-1&&cha));mid++)
add(f[l][r][pos][cha],dfs(l,mid,pos+1,0)*dfs(mid+1,r,pos,cha+1)%mod);
return f[l][r][pos][cha];
}
signed main()
{
memset(f,-1,sizeof(f));
n=read();
for(int i=1,len;i<=n;i++)
{
scanf("%s",ch+1);
len=strlen(ch+1);
Len=max(len,Len);
for(int j=1;j<=len;j++)
s[i][j]=(ch[j]=='?'?-1:ch[j]-'a'+1);
}
printf("%lld",dfs(1,n,1,0));
return 0;
}
T3 Huge Counting
解题思路
可重集排列问题。
组合数求方案数,由二维可以扩展到 k 维 \(\dfrac{(\sum x_i)!}{\prod (x_i-1)!}\)
然后直接大力 容斥+判断分数上下的 2 的数,奇加偶减。
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=10,Lg=50,mod=990804011;
int T,n,f[Lg+10][1<<N],l[N],r[N],lim[N];
void add(int &x,int y){x+=y;if(x>mod)x-=mod;else if(x<0)x+=mod;}
int work()
{
int ans=0;
for(int i=1;i<=n;i++)
if(lim[i]==-1)
return 0;
memset(f,0,sizeof(f));
f[Lg][(1<<n)-1]=1;
for(int i=Lg;i>=1;i--)
{
int st=0;
for(int j=1;j<=n;j++)
if((lim[j]>>i-1)&1)
st|=1<<j-1;
for(int sta=0;sta<(1<<n);sta++)
if(f[i][sta])
{
int com=sta&(st^((1<<n)-1));
add(f[i-1][com],f[i][sta]);
for(int j=1;j<=n;j++)
if(((sta>>j-1)&1)^1) add(f[i-1][com],f[i][sta]);
else if((st>>j-1)&1) add(f[i-1][com|(1<<j-1)],f[i][sta]);
}
}
for(int sta=0;sta<(1<<n);sta++)
add(ans,f[0][sta]);
return ans;
}
int solve()
{
n=read();
int ans=0;
for(int i=1;i<=n;i++)
l[i]=read()-1,r[i]=read()-1;
for(int sta=0,sym;sta<(1<<n);sta++)
{
sym=1;
for(int i=1;i<=n;i++)
if((sta>>i-1)&1) lim[i]=r[i];
else lim[i]=l[i]-1,sym*=-1;
add(ans,sym*work());
}
return (ans+mod)%mod;
}
signed main()
{
T=read();
while(T--) printf("%lld\n",solve());
return 0;
}
T4 字符消除2
解题思路
题目大意就是对于给出的字符串求出一个字典序最小的 01 串与该字符串的循环节相同。
Hash 预处理出前后缀相同的位置,计入一个数组 sta。
对于整个 sta 而言 \(sta_i\) 与 \(sta_{i-1}\) 的关系分为两种
\(sta_i\le sta_{i-1}\times 2\) 那么此时的 \(sta_i\) 这一段一定是有 \(sta_{i-1}\) 这个字符串的后缀和前缀的,因为前面已经是最优解,直接把前面的复制过来就好了。
\(sta_i>sta_{i-1}\times 2\) 此时一定除了相同的前后缀之外中间还有一段区间,因为要保证字典序最小,一定是填 0 最优。
但是这样可能会导致循环节过多,因此我们需要在某个位置填一个 1 ,但是暴力维护显然是不行的。
用 KMP 优化,每次向前面跳 next,然后判断当前的一段的长度是否是空出来区间长度的整数倍,如果是并且最后一位不是 1 ,那么就是一个多出来的循环节,需要把最后一位改成 1 。
code
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=2e5+10;
const ull base=1331ull;
int T,n,top,pos,sta[N],nxt[N];
ull has[N],p[N];
bool vis[N];
char ch[N];
void KMP(int l,int r)
{
for(int i=l;i<=r;i++)
{
while(pos>0&&vis[i]!=vis[pos+1]) pos=nxt[pos];
if(vis[i]==vis[pos+1]) pos++;
nxt[i]=pos;
}
}
void solve()
{
memset(nxt,0,sizeof(nxt));
memset(vis,false,sizeof(vis));
top=pos=0;
scanf("%s",ch+1);
n=strlen(ch+1);
for(int i=1;i<=n;i++)
has[i]=has[i-1]*base+ch[i];
for(int i=1;i<=n;i++)
if(has[i]==has[n]-has[n-i]*p[i])
sta[++top]=i;
if(sta[1]>1) vis[sta[1]]=true;
KMP(2,sta[1]);
for(int i=2;i<=top;i++)
if(sta[i]<=sta[i-1]*2)
{
for(int j=sta[i-1]+1;j<=sta[i];j++)
vis[j]=vis[j-sta[i]+sta[i-1]];
KMP(sta[i-1]+1,sta[i]);
}
else
{
KMP(sta[i-1]+1,sta[i]-sta[i-1]-1);
int x=pos,len=sta[i]-sta[i-1];
while(x)
{
if(!vis[x+1]&&!(len%(len-x-1)))
{
vis[len]=true;
break;
}
x=nxt[x];
}
if(!vis[x+1]&&!(len%(len-x-1)))
vis[len]=true;
while(pos>0&&ch[len]!=ch[pos+1]) pos=nxt[pos];
if(ch[len]==ch[pos+1]) pos++;
nxt[len]=pos;
for(int j=1;j<=sta[i-1];j++)
vis[j+len]=vis[j];
KMP(len+1,sta[i]);
}
for(int i=1;i<=n;i++)
printf("%d",vis[i]);
printf("\n");
}
signed main()
{
p[0]=1;for(int i=1;i<N;i++)p[i]=p[i-1]*base;
T=read();
while(T--) solve();
return 0;
}
8.19考试总结(NOIP模拟44)[Emotional Flutter·Medium Counting·Huge Counting·字符消除2 ]的更多相关文章
- 2021.8.19考试总结[NOIP模拟44]
T1 emotional flutter 把脚长合到黑条中. 每个黑条可以映射到统一区间,实际操作就是左右端点取模.长度大于$k$时显然不合法. 然后检查一遍区间内有没有不被黑条覆盖的点即可. 区间端 ...
- [考试总结]noip模拟44
这个真的是一个 \(nb\) 题. 考试快要结束的时候,在机房中只能听到此起彼伏的撕吼. 啊---------- 然后人们预测这自己的得分. \(\color{red}{\huge{0}}\) \(\ ...
- noip模拟44[我想我以后会碰见计数题就溜走的]
noip模拟44 solutions 这一场抱零的也忒多了,我也只有45pts 据说好像是把几套题里面最难的收拾出来让我们考得 好惨烈啊,这次的考试我只有第一题骗了40pts,其他都抱零了 T1 Em ...
- 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]
6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...
- 5.23考试总结(NOIP模拟2)
5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...
- 5.22考试总结(NOIP模拟1)
5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...
- Noip模拟44 2021.8.19
比较惊人的排行榜 更不用说爆零的人数了,为什么联赛会这么难!!害怕了 还要再努力鸭 T1 Emotional Flutter 考场上没切掉的神仙题 考率如何贪心,我们把黑色的条延长$s$,白色的缩短$ ...
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
- [考试总结]noip模拟23
因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...
- noip模拟44
A. Emotional Flutter 直接将所有黑块平移到 \([1-k,0]\) 的区间即可,然后找有没有没被覆盖过的整点 注意特判 \(1-k\) 以及 \(0\) 的可行性,考场这里写挂成 ...
随机推荐
- 重新整理数据结构与算法(c#)—— 二叉树排序树[二十二]
前言 什么是二叉堆排序呢? 就是上面这种,一个节点大于左节点,但是小于右节点,再我写的例子中会写出大于等于右节点. 那么如何让一个数组进行变成这种二叉树呢? 其实只要有规律就很简单. 第一个元素(0) ...
- locust分布式压测的Step Load及no web模式下的报表自动生成
Running Locust in Step Load ModeIf you want to monitor your service performance with different user ...
- 什么是token,为什么需要token
1.为什么需要token 随着互联网的发展,为了更安全,以及更好的用户体验,逐渐产生了token这个技术方案 之所以使用token是因为http/https协议本身是无状态的,不能进行信息的存储 (c ...
- ATC'22顶会论文RunD:高密高并发的轻量级 Serverless 安全容器运行时 | 龙蜥技术
简介: RunD可以在88毫秒内启动,并且在104核384GB内存的单节点上每秒启动超过200个安全容器. 编者按:目前的安全容器软件栈 - 包括 host 操作系统中的 cgroup.guest 操 ...
- 基于 Flink CDC 实现海量数据的实时同步和转换
简介: 徐榜江在 5.21 Flink CDC Meetup 的分享. 摘要:本文整理自 Apache Flink Committer,Flink CDC Maintainer,阿里巴巴高级开发工程师 ...
- DataFunTalk:阿里建设一站式实时数仓的经验分享
简介: 本文内容整理于阿里资深技术专家姜伟华在DataFunTalk上的演讲,为大家介绍阿里巴巴基于一站式实时数仓Hologres建设实时数仓的经验和解决方案. 导读:大数据计算正从规模化走向实时化, ...
- 【ESSD技术解读-01】 云原生时代,阿里云块存储 ESSD 快照服务如何被企业级数据保护所集成?
简介: 本文描述了阿里云块存储快照服务基于高性能 ESSD 云盘提升快照服务性能,提供轻量.实时的用户体验及揭秘背后的技术原理.依据行业发展及云上数据保护场景,为企业用户及备份厂商提供基于快照高级特 ...
- 如何保证 Serverless 业务部署更新的一致性?
简介: 代码在其他场景被更新,需要我们在当前得到感知,这个事情其实是非常重要的,和代码的安全发布密不可少.而此时,通过 Serverless Devs 是可以做到的. 作者|Anycodes 从我做 ...
- GRPC: 如何优雅关闭进程(graceful shutdown)
简介: 本文将介绍优雅关闭 gRPC 微服务.在进程收到关闭信号时,我们需要关闭后台运行的逻辑,比如,MySQL 连接等等. 介绍 本文将介绍优雅关闭 gRPC 微服务. 什么是优雅关闭? 在进程收 ...
- 探究 Java 应用的启动速度优化
简介: Java 的执行效率非常高,约为最快的C语言的一半.这在主流的编程语言中,仅次于C.Rust 和 C++.但在高性能的背后,Java 的启动性能差也令人印象深刻,大家印象中的 Java 笨重缓 ...