P3131 [USACO16JAN]子共七Subsequences Summing to Sevens

斯德哥尔摩

2018-10-21 20:40:56

Personal

[P3131 [USACO16JAN]子共七Subsequences Summing to Sevens](https://www.luogu.org/problemnew/show/P3131) 首先前缀和没的说。 然后有个定理: 设$seven[i]$表示前缀和模$7$的值,若存在$i<=j$且$seven[j]==seven[i]$,则区间$(i,j]$的和为$7$的倍数。 于是我们可以$O(n)$扫出$seven[i]==j,j\in[0,6]$第一次出现的位置$begin[j]$和最后一次出现的位置$end[j]$。 然后答案为$\max\{end[j]-begin[j]+1|j\in[0,6]\}$。 附代码: ```cpp #include<iostream> #include<algorithm> #include<cstdio> #define MAXN 50010 using namespace std; int n,ans=0; int start[7],end[7]; long long sum[MAXN]; inline int read(){ int date=0,w=1;char c=0; while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();} while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();} return date*w; } void work(){ for(int i=0;i<=6;i++)ans=max(ans,end[i]-start[i]); printf("%d\n",ans); } void init(){ n=read(); sum[0]=0; for(int i=1;i<=n;i++){ int x=read(); sum[i]=sum[i-1]+x; if(!start[sum[i]%7])start[sum[i]%7]=i; end[sum[i]%7]=i; } } int main(){ init(); work(); return 0; } ```