ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P8226樱点收集

2022-05-13 09:32:38  阅读:174  来源: 互联网

标签:bomb 收集 樱点 res sum P8226 rest ans numsakura


P8266

分析题意可以打一个很显然的\(O(n^2)\)暴力

丑陋的赛时代码 \(70pts\)

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\),显然有当$ sum[i] \mod k ==0\(时恰好在第i个关卡展开结界,那么可以维护一个\)ans\(数组用来记录不放bomb时前\)i$个关卡的贡献,则有

if(sum[i]%k==0){
	ans[i]=ans[i-1]+vis[i];
}
else ans[i]=ans[i-1];

接下来考虑放bomb,如果在位置\(j\)放了一个\(bomb\),\(1 \rightarrow j-1\)收集到的樱点还是对应的前缀和,也就是说对他们都没有影响,后面收集到的樱点为\(sum[i]-a[j]\)。如果\(sum[i]-a[j] \mod k==0\)才对答案有贡献,但是如果\(O(n^2)\)再算一遍显然不现实。所以我们倒着搞

学过数论的选手都晓得\(sum[i]-a[j] \mod k==0\)实际上为\(sum[i] \equiv a[j] \mod k\),维护一个数组\(rest\),下标为\(x \mod k\), \(rest[i]\)表示在\(i\)关卡之前放了一个bomb\(i\)关卡对答案的贡献,则有

for(int i=n;i>0;--i){//枚举bomb
    res=max(res,ans[i-1]+rest[a[i]%k]);
    rest[sum[i]%k]+=vis[i];
}

然后就结束了

$ \it Speak is nothing ,Show me the Code.$

#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;
}

标签:bomb,收集,樱点,res,sum,P8226,rest,ans,numsakura
来源: https://www.cnblogs.com/Chano/p/16265407.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有