CF1834 题解
CF1834 题解
A
考虑答案与元素位置无关,只与
序列中
序列中
时间复杂度
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
int a[N],n,s[N];
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
memset(a,0,sizeof(a));
memset(s,0,sizeof(s));
for(int i = 1;i <= n;i++) cin>>a[i],s[i] = s[i - 1] + a[i];
if(s[n] >= 0) cout<<((n - s[n]) % 4 == 0 ? 0 : 1)<<endl;
else cout<<((n / 2) % 2 == 0 ? (-s[n] + 1) / 2 : (-s[n] + 1) / 2 + 1)<<endl;
}
return 0;
}
B
考虑
时间复杂度
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
int n,m;
char a[N],b[N];
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%s",a + 1);
scanf("%s",b + 1);
n = strlen(a + 1);
m = strlen(b + 1);
if(n < m)
{
for(int i = n;i >= 1;i--) a[i + m - n] = a[i];
for(int i = 1;i <= m - n;i++) a[i] = '0';
}
int ans = 0;
for(int i = 1;i <= m;i++)
if(a[i] != b[i])
{
ans += (m - i) * 9 + abs(b[i] - a[i]);
break;
}
cout<<ans<<endl;
}
return 0;
}
C
既然Alice想要将步数最小化,那么她就要尽量将两个字符串之间的差异消掉。我们发现
宁愿当小丑也在所不惜,全力以赴地进行着必输的游戏......仅仅是他深爱着她。
上文说了,只有两种对应方式,所以Alice自然选的就是步数小的那个。我们发现由于Alice改变一次,Bob就要翻转一次,所以步数等于对应方式的差异数乘2,根据差异数的奇偶性和对应顺序决定是否需要-1(Bob最后一次翻之前就对应上了)
时间复杂度
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
char s[N],t[N];
int n;
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
scanf("%s",s + 1);
scanf("%s",t + 1);
int dif = 0,rdif = 0,step = 0,rstep = 0;
for(int i = 1;i <= n;i++) if(s[i] != t[i]) ++dif;
for(int i = 1;i <= n;i++) if(s[i] != t[n + 1 - i]) ++rdif;
step = dif << 1;
if(dif & 1) step--;
if(dif == 0) step = 0;
rstep = rdif << 1;
if(!(rdif & 1)) rstep--;
if(rdif == 0) rstep = 2;
cout<<min(step,rstep)<<endl;
}
return 0;
}
D
神犇jeefy有一个
考虑到对于一个人,如果他是极差中的最大值,那么所选的点就是他学过的所有点(对于学过的,多选一个他的高度就+1,最小值的高度可能+1,一定不劣;对于他没学过的,选了以后他的高度不变,最小值的高度可能+1,一定不优)。
所以我们可以枚举这个最大值是谁,可能的最小值与这个人可能有3种关系:不交,相交,最小值包含于这个人。先不考虑包含,这一部分很简单,我们尽量选一个人让他们不交,所以记录全场最大右端点和最小左端点即可,因为取这两个端点对应的线段一定是与中间的最大值交集最小的,与两边的交集大小取
对于包含关系,我们发现与最大值交集最小的,一定是包含于他的人中学的最少的人,考虑二维关系不好维护,就将人按照右端点排序,从小到大遍历右端点,在以左端点为下标的树状数组中找比当前左端点大的当中学的最少的人,就是这个最大值对应的答案。
时间复杂度
解释:代码中对于“比当前左端点大的”这个后缀操作,在离散化左端点时将其反序存储,转化为树状数组的前缀问题。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5,inf = 0x3f3f3f3f;
struct Seg{
int l,r;
}x[N];
int n,maxl,minr,m,xl[N],cnt = 0,inc[N];
map<int,int> rev;
struct BIT{
int a[N];
inline void init()
{
for(int i = 1;i <= n;i++) a[i] = inf;
}
inline int lowbit(int x)
{
return x & (-x);
}
inline int query(int x)
{
if(!x) return inf;
return min(query(x - lowbit(x)),a[x]);
}
inline void modify(int x,Seg k)
{
if(x > cnt) return;
a[x] = min(a[x],k.r - k.l + 1);
modify(x + lowbit(x),k);
}
}p;
inline bool cmp(Seg a,Seg b)
{
if(a.r ^ b.r) return a.r < b.r;
else return a.l > b.l;
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n>>m;
maxl = 0,minr = 2e9;cnt = 0;
rev.clear();
p.init();
for(int i = 1;i <= n;i++)
{
cin>>x[i].l>>x[i].r;
xl[i] = x[i].l;
maxl = max(maxl,x[i].l);
minr = min(minr,x[i].r);
}
sort(xl + 1,xl + n + 1);
cnt = unique(xl + 1,xl + n + 1) - (xl + 1);
for(int i = 1;i <= cnt;i++) rev[xl[i]] = cnt + 1 - i;
sort(x + 1,x + n + 1,cmp);
for(int i = 1;i <= n;i++)
{
inc[i] = p.query(rev[x[i].l]);
p.modify(rev[x[i].l],x[i]);
}
int ans = 0;
for(int i = 1;i <= n;i++)
{
int inter = min(min(max(x[i].r - maxl + 1,0),max(minr - x[i].l + 1,0)),inc[i]);
ans = max(ans,(x[i].r - x[i].l + 1 - inter) << 1);
}
cout<<ans<<endl;
}
return 0;
}
E
我们发现如果一个素数是一些数的
考虑到一个暴力,对于每个点
这样暴力复杂度是
按这个写一发,你就会发现你AC了。
因为这样优化后,时间复杂度就有了保证,考虑向右扫时每次
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5,M = 6e6 + 5;
typedef long long ll;
ll a[N],st[20][N],n;
int prime[N * 5],tot = 0,lim;
bool vis[M];
inline void init()
{
for(int i = 2;i <= M - 1;i++)
{
if(!vis[i])
prime[++tot] = i;
for(int j = 1;j <= tot && 1ll * i * prime[j] <= M - 1;j++)
{
vis[i * prime[j]] = 1;
if(!(i % prime[j])) break;
}
}
memset(vis,0,sizeof(vis));
}
inline int lcm(int x,int y)
{
if(x == -1 || y == -1) return -1;
ll p = 1ll * x / __gcd(x,y) * y;
if(p > lim) return -1;
return p;
}
inline int fd(int x,int &val)
{
for(int i = 19;i >= 1;i--)
if(lcm(val,st[i][x]) == val) x += (1 << i) - 1;
val = lcm(val,st[0][x + 1]);
return x + 1;
}
int main()
{
int T;
init();
cin>>T;
while(T--)
{
cin>>n;lim = prime[n + 1];
for(int i = 1;i <= lim;i++) vis[i] = 0;
for(int i = 1;i <= n;i++)
{
cin>>a[i];st[0][i] = a[i];
if(st[0][i] > lim) st[0][i] = -1;
}
for(int i = 1;i <= 19;i++)
for(int j = 1;j <= n;j++)
{
if((1 << i) + j - 1 > n) st[i][j] = -1;
else st[i][j] = lcm(st[i - 1][j],st[i - 1][j + (1 << (i - 1))]);
}
for(int i = 1;i <= n;i++)
{
int tp = i,now = st[0][i];
while(tp <= n && now != -1)
{
vis[now] = 1;
tp = fd(tp,now);
}
}
for(int i = 1;i <= lim;i++)
if(!vis[i])
{
cout<<i<<endl;
break;
}
}
return 0;
}
F
咕。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话