Problem G. Generators

复杂度 基本上控制在 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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值