Codeforces Round 938 (Div. 3) E
有点意思的题目。
首先可以得到的一个结论就是,如果k能够完成,那唯一的操作方法就是从前往后,遇到0就使用,把这个点变成1。
那么我们就能够做到O(n)验证了,然后发现O(n^2)可以接受,就过了。
但是我因为滥用数据结构,导致我认为验证需要O(nlogn)然后5000又刚刚好跑不过去。
所以觉得做法假了,尝试从减少验证的次数上下手。
首先可以发现一个性质,就是如果k=m的时候是可以分解完成的,那么m的所有因子作为k也是可以的,
那假如能够证明,所有合法的k都是一个数字的因子的话,那这题就可以通过质因数分解的方法来做到两个log
很明显,不可以。反例:011110 k=5和2都可以。
然后就做法假了。
死因:没有发现滑动窗口是不需要动态维护前缀和的,只需要O(1)即可维护。
这一点记下来,以后还是尽量少用树状数组吧。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read() {
char c=getchar();int a=0,b=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
int n,a[5001],ans,b[5001];
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int T=read();
while(T--)
{
n=read();
string s;
cin>>s;
for(int i=1;i<=n;i++)
{
a[i]=s[i-1]-'0';
}
int ans=0;
for(int i=n;i>=1;i--)
{
for(int j=1;j<=n;j++)
{
b[j]=0;
}
int now=0;
for(int j=1;j<=n-i+1;j++)
{
now+=b[j];
if((a[j]+now)%2==0)
{
b[j]++;
now++;
b[j+i]++;
}
}
bool flag=0;
for(int j=n-i+2;j<=n;j++)
{
now+=b[j];
if((a[j]+now)%2==0)
{
flag=1;
break;
}
}
if(flag==0)
{
ans=i;
break;
}
}
cout<<ans<<endl;
}
return 0;
}
upd:2024 4 10
才发现放错代码了。。放成了上一份的代码
【推荐】FFA 2024大会视频回放:Apache Flink 的过去、现在及未来
【推荐】中国电信天翼云云端翼购节,2核2G云服务器一口价38元/年
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 使用 .NET Core 实现一个自定义日志记录器
· [杂谈]如何选择:Session 还是 JWT?
· 硬盘空间消失之谜:Linux 服务器存储排查与优化全过程
· JavaScript是按顺序执行的吗?聊聊JavaScript中的变量提升
· [杂谈]后台日志该怎么打印
· 2000 Star,是时候为我的开源项目更新下功能了
· 面试官:DNS解析都整不明白,敢说你懂网络?我:嘤嘤嘤!
· [WPF UI] 为 AvalonDock 制作一套 Fluent UI 主题
· 基于.NET WinForm开发的一款硬件及协议通讯工具
· 内网穿透之http代理服务器