P8226樱点收集
分析题意可以打一个很显然的暴力
丑陋的赛时代码
void work(){
n=read(),m=read(),k=read();
for(int i=1;i<=m;++i){
int x=read();vis[x]=1;
}
for(int i=1;i<=n;++i){
a[i]=read();
}
int res=0;
for(int bomb=0;bomb<=n;++bomb){
int numsakura=0,ans=0;
for(int i=1;i<=n;++i){
if(bomb==i)continue;
if(numsakura+a[i]>k){
numsakura=(numsakura+a[i])%k;
if(numsakura==0 && vis[i]){
ans++;
}
}
else if(numsakura+a[i]==k){
numsakura=0;
if(vis[i]){
ans++;
}
}
else numsakura+=a[i];
}
res=max(res,ans);
}
printf("%d\n",res);
}
int main(){
work();
return 0;
}
接下来考虑动一下脑子
对于每一个关卡,只有在最后在收集完最后一个樱点结界展开时才对答案有贡献,所以我们只考虑恰好的时刻,忽略中间结界展开的过程。
先不考虑放bomb,维护一个前缀和,显然有当$ sum[i] \mod k ==0ansi$个关卡的贡献,则有
if(sum[i]%k==0){
ans[i]=ans[i-1]+vis[i];
}
else ans[i]=ans[i-1];
接下来考虑放bomb,如果在位置放了一个,收集到的樱点还是对应的前缀和,也就是说对他们都没有影响,后面收集到的樱点为。如果才对答案有贡献,但是如果再算一遍显然不现实。所以我们倒着搞
学过数论的选手都晓得实际上为,维护一个数组,下标为, 表示在关卡之前放了一个bomb关卡对答案的贡献,则有
for(int i=n;i>0;--i){//枚举bomb
res=max(res,ans[i-1]+rest[a[i]%k]);
rest[sum[i]%k]+=vis[i];
}
然后就结束了
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0;char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9'){
x=(x<<1)+(x<<3)+(c^'0');c=getchar();
}
return x;
}
const int maxn=3e5+5;
const int maxk=1e6+5;
int n,m,k;
int a[maxn];
int sum[maxn];
bool vis[maxn];
int rest[maxk];
int ans[maxn];
void work(){
n=read(),m=read(),k=read();
for(int i=1;i<=m;++i){
int x=read();vis[x]=1;
}
for(int i=1;i<=n;++i){
a[i]=read();
sum[i]=sum[i-1]+a[i];
}
int res=0;
for(int i=1;i<=n;++i){
ans[i]=ans[i-1];
if(sum[i]%k==0){
ans[i]++;
}
}
for(int i=n;i>0;--i){
res=max(res,ans[i-1]+rest[a[i]%k]);
rest[sum[i]%k]+=vis[i];
}
printf("%d\n",res);
}
int main(){
work();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了