Generators

Problem G. Generators
Input file: generators.in
Output file: generators.out
Little Roman is studying linear congruential generators — one of the oldest and best known pseudorandom
number generator algorithms. Linear congruential generator (LCG) starts with a non-negative
integer number x0 also known as seed and produces an infinite sequence of non-negative integer numbers xi
(0 ≤ xi < c) which are given by the following recurrence relation:
xi+1 = (axi + b) mod c
here a, b, and c are non-negative integer numbers and 0 ≤ x0 < c.
Roman is curious about relations between sequences generated by different LCGs. In particular, he has
n different LCGs with parameters a(j), b(j), and c(j)
for 1 ≤ j ≤ n, where the j-th LCG is generating a sequence x(j) i
. He wants to pick one number from each of the sequences generated by each LCG so that
the sum of the numbers is the maximum one, but is not divisible by the given integer number k.
Formally, Roman wants to find integer numbers tj ≥ 0 for 1 ≤ j ≤ n to maximize s =
Pn
j=1 x
(j)
tj
subject
to constraint that s mod k 6= 0.
Input
The first line of the input file contains two integer numbers n and k (1 ≤ n ≤ 10 000, 1 ≤ k ≤ 109
).
The following n lines describe LCGs. Each line contains four integer numbers x
(j)
0
, a
(j)
, b
(j)
, and c
(j)
(0 ≤ a
(j)
, b(j) ≤ 1000, 0 ≤ x
(j)
0 < c(j) ≤ 1000).
Output
If Roman’s problem has a solution, then write on the first line of the output file a single integer s —
the maximum sum not divisible by k, followed on the next line by n integer numbers tj (0 ≤ tj ≤ 109
)
specifying some solution with this sum.
Otherwise, write to the output file a single line with the number −1.
Sample input and output
generators.in generators.out
2 3
1 1 1 6
2 4 0 5
8
4 1
2 2
0 7 2 8
2 5 0 6
-1
In the first example, one LCG is generating a sequence 1, 2, 3, 4, 5, 0, 1, 2, . . ., while the other LCG a
sequence 2, 3, 2, 3, 2, . . ..
In the second example, one LCG is generating a sequence 0, 2, 0, 2, 0, . . ., while the other LCG a sequence

2, 4, 2, 4, 2, . . ..


题意:

给你几组数据,让你求出这几组数据的LCG,之后从每组的LCG值选一个加起来,问满足sum%k!=0时sum的值,并输出每组LCG选出来的值的位置。

思路:

每组LCG的次大值和最大值两两组合就是答案。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
	int id,val;
};
node a[10005][2];
int vis[1005];
int dp[10005];
int ans[10005];
int main()
{
	int n,k;
	freopen("generators.in","r",stdin);
  freopen("generators.out","w",stdout);
	while(scanf("%d%d",&n,&k)!=EOF)
	{
		memset(a,0,sizeof(a));
		int x,a1,b,c;int sum=0;
		for(int i=1;i<=n;i++)
		{
			memset(vis,0,sizeof(vis));
			scanf("%d%d%d%d",&x,&a1,&b,&c);
			int t=x,cnt=0;vis[t]=1;
			a[i][1].id=0,a[i][1].val=0;
			a[i][0].id=0,a[i][0].val=0;
			for(int j=0;j<c;j++)
			{
				if(a[i][1].val<x)
				{
					a[i][0].val=a[i][1].val,a[i][0].id=a[i][1].id;
					a[i][1].val=x,a[i][1].id=j;
				}
				else if(a[i][0].val<x)
				{
					a[i][0].val=x,a[i][0].id=j;
				}
				cnt++;
				x=(a1*x+b)%c;
				if(vis[x]) break;
				vis[x]=1;
			}
			if(cnt==1)
			{
				a[i][0].val=a[i][1].val;
				a[i][0].id=a[i][1].id;
            }
            sum+=a[i][1].val;
            ans[i]=a[i][1].id;
		}
		if(sum%k!=0)
		{
			printf("%d\n",sum);
			for(int i=1;i<=n;i++)
			{
				printf("%d ",a[i][1].id);
			}
			printf("\n");
		}
		else
		{
			int tmp=-1,t1=-1;
			for(int i=1;i<=n;i++)
			{
				if(tmp<sum-a[i][1].val+a[i][0].val)
				{
					if((sum-a[i][1].val+a[i][0].val)%k!=0)
					{
						tmp=sum-a[i][1].val+a[i][0].val;
					t1=i;
					}
				}
			}
			ans[t1]=a[t1][0].id;
			if(tmp%k==0||tmp==-1) printf("-1\n");
			else
			{
				printf("%d\n",tmp);
				for(int i=1;i<=n;i++)
				printf("%d ",ans[i]);
				printf("\n");
			}
		}
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值