Gym - 100851G:Generators(人尽皆知但是WA题)
题意:现在有函数,每一项Xi=(A*X(i-1)+B)%C。现在给定N个函数以及K:X0,A,B,C。然你再每个函数选择一个数,使得其和最大,而且不被K整除。
X0,A,B,C<=1e3 ;K<=1e9
思路:因为C比较小,我们可以找到循环节(不一定是从0开始就循环了,所以用vis判定是否出现过)。然后保存每个函数的最大值,以及不同余的第二大值。
如果所有数的最大值不被K整除,那么最多有一个数被第二大替代
(一个简单题我居然wa了几发,所以还是写一下。
#include<bits/stdc++.h> #define pii pair<int,int> #define F first #define S second #define mp make_pair using namespace std; const int maxn=10010; pii Mx[maxn][2]; int pos[maxn]; int a[maxn],vis[maxn]; int main() { freopen("generators.in","r",stdin); freopen("generators.out","w",stdout); int N,K,i,j,x,A,B,C,ans=0,tmp,L; scanf("%d%d",&N,&K); for(i=1;i<=N;i++){ scanf("%d",&a[0]); Mx[i][0]=mp(a[0],0); scanf("%d%d%d",&A,&B,&C); vis[a[0]]=1; L=0; for(j=1;;j++){ a[j]=(a[j-1]*A+B)%C; if(vis[a[j]]) break; if(a[j]>Mx[i][0].F) Mx[i][0]=mp(a[j],j); vis[a[j]]=1; L++; } Mx[i][1]=mp(-1,-1); for(j=0;j<=L;j++) if(a[j]%K!=Mx[i][0].F%K&&a[j]>Mx[i][1].F) Mx[i][1]=mp(a[j],j); for(j=0;j<=L;j++) vis[a[j]]=0; } for(i=1;i<=N;i++) ans+=Mx[i][0].F; for(i=1;i<=N;i++) pos[i]=Mx[i][0].S; if(ans%K!=0) printf("%d\n",ans); else { int change=0,sum=-1; for(i=1;i<=N;i++){ if(Mx[i][1].F!=-1){ if(ans-Mx[i][0].F+Mx[i][1].F>sum) sum=ans-Mx[i][0].F+Mx[i][1].F,change=i; } } if(sum==-1||sum%K==0) { puts("-1"); return 0; } printf("%d\n",sum); pos[change]=Mx[change][1].S; } for(i=1;i<=N;i++) printf("%d ",pos[i]); return 0; }
It is your time to fight!