复杂度 基本上控制在 n^2.
这种最大值得问题,有点像随机数的感觉。 不知道怎么证明,为什么最多只需要置换一个 最大数就可以了。 这样得到的结果 就会等价于 取遍所有的情况。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i,a,b) for(int i=a;i<b;++i)
const int N=10010;
struct node{
int x,pos;
node(int _x=0,int _pos=0){
x=_x,pos=_pos;
}
bool operator<(const node& b)const{
return x<b.x;
}
};
vector<node> vec[N];
int vis[N],pos[N];
/*
2 3
1 1 1 6
2 4 0 5
2 2
0 7 2 8
2 5 0 6
*/
int main(){
freopen("generators.in","r",stdin);
freopen("generators.out","w",stdout);
LL n,k;
scanf("%I64d %I64d",&n,&k);
LL ans=0;
LL x,x0,a,b,c;
for(int i=1;i<=n;i++){
scanf("%I64d %I64d %I64d %I64d",&x0,&a,&b,&c);
vec[i].push_back(node(x0,0));
fill(vis,vis+c+1,0);
vis[x0]=1;
for(int j=1;;j++){
x=(a*x0+b)%c;
if(vis[x])break;
vis[x]=1;
vec[i].push_back(node(x,j));
x0=x;
}
//printf("****\n");
//for(int j=0;j<vec[i].size();j++)printf(" %d",vec[i][j].x);
//printf("\n");
sort(vec[i].begin(),vec[i].end());
ans+=vec[i][vec[i].size()-1].x;
pos[i]=vec[i][vec[i].size()-1].pos;
}
//printf("ans:%I64d\n",ans);
LL tmp=ans,change=-1,pp=-1;
if(ans%k!=0){
printf("%I64d\n",ans);
rep(i,1,n+1)printf("%d%c",pos[i],i==n?'\n':' ');
return 0;
}
else{
for(int i=1;i<=n;i++){
int sz=vec[i].size();
tmp-=vec[i][sz-1].x;
for(int j=sz-1;j>=0;j--){
if((tmp+vec[i][j].x)%k!=0){
if(change==-1||tmp+vec[i][j].x>ans){
change=i;
pp=vec[i][j].pos;
ans=tmp+vec[i][j].x;
}
break;
}
}
tmp+=vec[i][sz-1].x;
}
}
if(change!=-1){
pos[change]=pp;
printf("%I64d\n",ans);
rep(i,1,n+1)printf("%d%c",pos[i],i==n?'\n':' ');
}else{
printf("-1\n");
}
return 0;
}