码迷,mamicode.com
首页 > 其他好文 > 详细

Gym100851G Generators 思维 (鸽笼原理)

时间:2020-03-28 21:55:30      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:stdin   最大   c++   targe   std   min   lan   out   原理   

网址:https://codeforces.com/gym/100851

题意:

考虑如下线性同余发生器:$x=(a*x+b)mod$ $c$,给出$1e4$个线性同余发生器,在这些线性同余发生器生成的数的序列中每一个序列都任意挑一个数,使得它们的和最大并且不被$k$整除,输出和的值和各个位置,如果不存在输出$-1$。$c\leq1e3$。

题解:

线性同余发生器的值一定在不超过$c$个数就重复循环。所以只需要取其生成的前$c$个数的第k大。如果它们的和不被$k$整除,直接输出即可,如果被$k$整除,找到某个序列的第二大,使其和第一大的差值最小,且差值不被$k$整除,换上这个第二大即可。

(很奇怪,我不知道为什么我排序了还不能直接按顺序取第二大而是需要更新,不然会$WA$)。

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
typedef long long ll;
vector<pair<int, int> >v;
pair<int, int>p[N], dif[N];
bool vis[1005];
int main()
{
#ifndef _Aya
	//freopen("generators.in", "r", stdin);
	//freopen("generators.out", "w", stdout);
#endif
	int n, k, a, b, c, x;
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; ++i)
	{
		memset(vis, 0, sizeof(vis));
		v.clear();
		scanf("%d%d%d%d", &x, &a, &b, &c);
		v.push_back(make_pair(x, 0));
		vis[x] = 1;
		for (int j = 1; j < c; ++j)
		{
			x = (a * x + b) % c;
			if (!vis[x])
				v.push_back(make_pair(x, j)), vis[x] = 1;
			else
				break;
		}
		dif[i] = make_pair(-1, -1);
		sort(v.begin(), v.end(), greater<pair<int, int> >());
		p[i] = v[0];
		for (int j = 1; j < v.size(); ++j)
			if ((v[0].first - v[j].first) % k != 0 && v[j].first > dif[i].first)
				dif[i] = v[j];
		assert(p[i].first > dif[i].first);
	}
	ll sum = 0;
	for (int i = 1; i <= n; ++i)
		sum += p[i].first;
	if (sum % k)
	{
		printf("%lld\n", sum);
		for (int i = 1; i <= n; ++i)
			printf("%d%c", p[i].second, " \n"[i == n]);
	}
	else
	{
		int minn = 1e4, minpos = 0;
		for (int i = 1; i <= n; ++i)
			if (dif[i].second != -1 && p[i].first - dif[i].first < minn)
				minn = p[i].first - dif[i].first, minpos = i;
		if (!minpos)
			printf("-1\n");
		else
		{
			p[minpos] = dif[minpos];
			sum -= minn;
			printf("%lld\n", sum);
			for (int i = 1; i <= n; ++i)
				printf("%d%c", p[i].second, " \n"[i == n]);
		}
	}
	return 0;
}

 

Gym100851G Generators 思维 (鸽笼原理)

标签:stdin   最大   c++   targe   std   min   lan   out   原理   

原文地址:https://www.cnblogs.com/Aya-Uchida/p/12589389.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!