P1360 [USACO07MAR]Gold Balanced Lineup G(前缀和&Hash)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1360 [USACO07MAR]Gold Balanced Lineup G(前缀和&Hash)相关的知识,希望对你有一定的参考价值。
P1360 [USACO07MAR]Gold Balanced Lineup G(前缀和&Hash)
瓶颈之处在于:如何快速判断一个区间的m种能力和相等。
显然可以预处理所有能力的前缀和。
区间满足的条件是 m m m种能力的前缀和之差都相同。
即 p r e R pre_R preR的所有能力减去一个相同的值,等于 p r e L − 1 pre_{L-1} preL−1。
因此这两个前缀和在某种意义上等价的。
因此我们尝试找到一个基准值,比如以第一个能力为基准,我们始终都让第一个能力为0,当不为0时我们就进行所有能力减1的操作,这样我们就能保证两个前缀和具有相同的值。
然后我们就可以hash或者map来储存这个形式的前缀和数组,取最值即可、
code
// Problem: P1360 [USACO07MAR]Gold Balanced Lineup G
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1360
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-07-03 10:18:20
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
map<ull,int>mp;
int n,m,ans;
vector<int>a;
int base=131;
ull Hash(){
ull h[33]={};
for(int i=0;i<m;i++)
h[i+1]=h[i]*base+a[i];
return h[m];
}
int main(){
scanf("%d%d",&n,&m);a.resize(m);
mp[Hash()]=0;
for(int i=1;i<=n;i++){
int x;scanf("%d",&x);
for(int j=0;j<m;j++)
if(x>>j&1) a[j]++;
if(x&1) for(int j=0;j<m;j++) a[j]--;
ull y=Hash();
if(mp.count(y)) ans=max(ans,i-mp[y]);
else mp[y]=i;
}
printf("%d\\n",ans);
return 0;
}
以上是关于P1360 [USACO07MAR]Gold Balanced Lineup G(前缀和&Hash)的主要内容,如果未能解决你的问题,请参考以下文章
[USACO07MAR]黄金阵容均衡Gold Balanced L…(洛谷 1360)
[USACO07MAR]黄金阵容均衡Gold Balanced L… map
[USACO 2012 Mar Gold] Large Banner
bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列*