BZOJ 3671 NOI2014 随机数生成器 贪心+暴力

题目大意:。。。。。有点长自己看吧

首先既然是排序后的序列字典序最小,那么一定要选尽量小的数字走

然后T是1~m*n的序列 所以不存在重复(一开始我居然把这个条件看漏了)

好的这题贪心

每次选择没有被标记的最小点,然后把左下方和右上方都标记掉(记得标记重复时break,不然就挂了)

注意5000*5000的数组开两个int就是极限了 开多了妥妥MLE 所以T数组记得重复利用

暴力跑了38秒 不过这题每一行能够选择的区域一定是连续的 可以对于每一行维护一个l和r 每次更新取最值即可 这个代码跑了28秒 还是好慢QAQ

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 5010
using namespace std;
typedef long long ll;
int T[M*M],map[M][M],l[M],r[M];
ll seed,a,b,c,d;
int n,m,q;
inline int Rand()
{
	return seed=(a*seed*seed%d+b*seed%d+c)%d;
}
void kill(int x,int y)
{
	int i;
	for(i=1;i<x;i++)
		r[i]=min(r[i],y);
	for(i=x+1;i<=m;i++)
		l[i]=max(l[i],y);
}
int main()
{
	int i,j,k,x,y,flag=0;
	cin>>seed>>a>>b>>c>>d;
	cin>>m>>n>>q;
	for(i=1;i<=m;i++)
		r[i]=n;
	for(i=1;i<=m*n;i++)
		T[i]=i,swap(T[i],T[Rand()%i+1]);
	for(i=1;i<=q;i++)
	{
		scanf("%d%d",&x,&y);
		swap(T[x],T[y]);
	}
	k=0;
	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++)
			map[i][j]=T[++k];
	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++)
			T[map[i][j]]=i<<16|j;
	for(i=1;i<=m*n;i++)
	{
		x=T[i]>>16;
		y=T[i]&65535;
		if(y>=l[x]&&y<=r[x])
		{
			if(flag)
				putchar(' ');
			flag=1;
			printf("%d",map[x][y]);
			kill(x,y);
		}
	}
}
时间: 2024-10-28 11:54:13

BZOJ 3671 NOI2014 随机数生成器 贪心+暴力的相关文章

【bzoj3671】[Noi2014]随机数生成器 贪心

题目描述 输入 第1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子.第2行包含三个整数 N,M,Q ,表示小H希望生成一个1到 N×M 的排列来填入她 N 行 M 列的棋盘,并且小H在初始的 N×M 次交换操作后,又进行了 Q 次额外的交换操作.接下来 Q 行,第 i 行包含两个整数 u_i,v_i,表示第 i 次额外交换操作将交换 T_(u_i )和 T_(v_i ) 的值. 输出 输出一行,包含 N+M-1 个由空格隔开的正整数,表示可以得到的字

【BZOJ3671】[Noi2014]随机数生成器 暴力

[BZOJ3535][Noi2014]随机数生成器 Description Input 第1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子.第2行包含三个整数 N,M,Q ,表示小H希望生成一个1到 N×M 的排列来填入她 N 行 M 列的棋盘,并且小H在初始的 N×M 次交换操作后,又进行了 Q 次额外的交换操作.接下来 Q 行,第 i 行包含两个整数 u_i,v_i,表示第 i 次额外交换操作将交换 T_(u_i )和 T_(v_i ) 的值.

NOI2014 随机数生成器.

3757. [NOI2014]随机数生成器 (Standard IO) Time Limits: 5000 ms  Memory Limits: 262144 KB Description Input 输入文件的第 1 行包含 5 个整数,依次为 x0, a, b, c, d,描述小 H 采用的随机数生成算法所需的随机种子. 第 2 行包含三个整数 N, M, Q,表示小 H 希望生成一个 1 到 N × M 的排列来填入她 N 行 M 列的棋盘,并且小 H 在初始的 N × M 次交换操作后,

bzoj3671 [Noi2014]随机数生成器

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3671 [题解] 贪心从1...n*m取,开两个5000*5000的数组就够了,可以重复利用,坐标可以压到一个int里. 每次暴力标记不能访问的,标到已经有标记的就不用标了因为后面的肯定前面已经标记过了. 均摊复杂度就对了.复杂度$O(nm)$. 这破题还卡PE.. # include <stdio.h> # include <string.h> # include <i

BZOJ 2875: [Noi2012]随机数生成器( 矩阵快速幂 )

矩阵快速幂...+快速乘就OK了 -------------------------------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; typedef long long ll; ll MOD, a, c, x, n, g; ll MUL(ll a, ll b) { ll ans = 0; for(; b; b >>= 1

BZOJ 3671 NOI 2014 随机数生成器 贪心

题目大意:实在是太难说明了,自己看pdf吧.. 思路:优先按照它说明的方法处理数组,然后为了让数列中尽可能多的出现小的数字,所以1是必须要出现的,这样才能使整个数列的排序后字典序最小.我们思考,如果2也能在这个数列中那就最好不过了,但是2有可能不在这个数列里,就是2在走了1就不可能走的地方的话,就不能走2了.所以从小到大枚举数字,如果当前数字能走,就输出,然后标记所有走了这个节点就不能走的节点.空间比较紧,5000*5000可以开int*2+bool*1,极限了.. CODE: #include

BZOJ3671 [Noi2014]随机数生成器 【贪心】

题目链接 BZOJ3671 题解 模拟题意生成矩阵贪心从小选择即可 每选择一个,就标记其左下右上矩阵 由于每次都是标记一个到边界的矩阵,所以一旦遇到标记过就直接退出即可,可以保证复杂度 还有就是空间和时间有点卡 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<map> #define R

[bzoj 2875][noi2012]随机数生成器

传送门 Description 栋栋最近迷上了随机算法,而随机数是生成随机算法的基础.栋栋准备使用线性同余法(Linear Congruential Me thod)来生成一个随机数列,这种方法需要设置四个非负整数参数m,a,c,X[0],按照下面的公式生成出一系列随机 数X[n]X[n+1]=(aX[n]+c)mod m其中mod m表示前面的数除以m的余数.从这个式子可以看出,这个序列的下一个数 总是由上一个数生成的.用这种方法生成的序列具有随机序列的性质,因此这种方法被广泛地使用,包括常用

BZOJ 3122 SDOI2013 随机数生成器

一大堆边界一开始并不知道,胡乱判了几个之后一直WA 无奈之下只好去下载了数据,然后就疯狂判各种奇怪的边界了 刨去边界问题 首先我们考虑a=1的情况 x1+k*b=t(mod p) ex_gcd即可解 考虑a>1的情况 令S=X+b/(a-1) 原式就变成了一个等比数列 即S1*a^k=(t+b/(a-1))(mod p) 移项之后BSGS解即可 其他边界都可以O(1)判断 #include<cstdio> #include<cstring> #include<iostr