P1360 [USACO07MAR]Gold Balanced Lineup G
阿新 • • 發佈:2020-08-12
P1360 題解
思路
設\(sum[t][i]\)為截至第t天第i項能力的提升總次數。
由題意可知對每一個均衡時期\([t_1,t_2]\),\(\forall 1\leq i \leq m,sum[t_2][i]-sum[t_1-1][i]\)都相等。
- 由上,對於每個\(t\),可以將序列\(sum[t]\)的每個數減去\(sum[t][1]\),得到一個序列\(f\)(長為\(m\)),它對應值\(t\)。
- 也可以用差分的方法構造序列\(f\),使\(f[i]=sum[t][i]-sum[t][i-1](1\leq i\leq m-1\))。
可以用一個數據結構(例如map對映或者Hash表)維護這個序列集合。
對於每個\(t\)
程式碼
程式碼一:
#include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<map> #define N 100010 #define M 50 #define P 13331 using namespace std; typedef unsigned long long ull; int n,m; int f[M]; map<ull,int>mp; int read(){ int x=0,f=1;char c=getchar(); while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar(); while(c>='0' && c<='9') x=x*10+c-48,c=getchar(); return x*f; } ull Hash(){ ull a=0; for(int i=1;i<=m;i++) a=a*P+f[i]; return a; } int main(){ n=read(),m=read(); int ans=0; mp[Hash()]=0; for(int i=1;i<=n;i++){ int a=read(); for(int j=0;j<m;j++) if(a&(1<<j)) ++f[j+1]; if(a&1) for(int j=1;j<=m;j++) f[j]--; ull H=Hash(); if(mp.find(H)!=mp.end()) ans=max(ans,i-mp[H]); else mp[H]=i; } printf("%d\n",ans); return 0; }
程式碼二:
#include<iostream> #include<algorithm> #include<string> #include<cstdio> #include<cstdlib> #include<cstring> #include<vector> #include<map> using namespace std; int n,m,sum[32],ans; vector<int>b; map<vector<int>,int>h; int main() { scanf("%d%d",&n,&m); for(int i=1;i<m;i++) b.push_back(0); h[b]=0; for(int i=1,a;i<=n;i++) { scanf("%d",&a); b.clear(); for(int j=0;j<m;j++) { if(a&(1<<j)) sum[j]++; if(j) b.push_back(sum[j]-sum[j-1]); } if(h.find(b)!=h.end()) ans=max(ans,i-h[b]); else h[b]=i; } printf("%d",ans); return 0; }