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 <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e3 + 1;
const int mod = 1e9+7;

int mp[M][M];
int a[M * M], xc, A, B, C, D, n, m, T;
inline int gnext(int x) {
    return (1ll * A * x % D * x % D + 1ll * B * x % D + C) % D;
}

# define id(i, j) (((i)-1) * m + (j))

int main() {
    int Q;
    cin >> xc >> A >> B >> C >> D;
    cin >> n >> m >> Q; T = n*m;
    for (int i=1; i<=T; ++i) a[i] = i;
    for (int i=1; i<=T; ++i) {
        xc = gnext(xc);
        swap(a[i], a[xc % i + 1]);
    }
    while(Q--) {
        scanf("%d%d", &A, &B);
        swap(a[A], a[B]);
    }
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=m; ++j)
            mp[i][j] = a[id(i, j)];
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=m; ++j)
            a[mp[i][j]] = id(i, j), mp[i][j] = 0;
    int ux, uy, vx, vy, x, y, ok = 1;
    ux = n, uy = m, vx = 1, vy = 1;
    for (int i=1; i<=T; ++i) {
        x = (a[i] - 1) / m + 1;
        y = a[i] - (x-1) * m;
        if(!mp[x][y]) {
            if(ok) printf("%d", i), ok = 0;
            else printf(" %d", i);
            for (int a=x+1; a<=n; ++a)
                for (int b=y-1; b; --b) {
                    if(mp[a][b]) break;
                    mp[a][b] = 1;
                }
            for (int a=x-1; a; --a)
                for (int b=y+1; b<=m; ++b) {
                    if(mp[a][b]) break;
                    mp[a][b] = 1;
                }
        }
    }
    puts("");
    return 0;
}

时间: 2024-11-05 00:16:06

bzoj3671 [Noi2014]随机数生成器的相关文章

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

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

【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]随机数生成器 贪心

题目描述 输入 第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]随机数生成器

优先按照它说明的方法处理数组 然后为了让数列中尽可能多的出现小的数字 所以1是必须要出现的,这样才能使整个数列的排序后字典序最小. 我们思考,如果2也能在这个数列中那就最好不过了 但是2有可能不在这个数列里,就是2在走了1就不可能走的地方的话,就不能走2了. 所以从小到大枚举数字,如果当前数字能走,就输出,然后标记所有走了这个节点就不能走的节点. #include<algorithm> #include<iostream> #include<cstdlib> #incl

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

题目大意:.....有点长自己看吧 首先既然是排序后的序列字典序最小,那么一定要选尽量小的数字走 然后T是1~m*n的序列 所以不存在重复(一开始我居然把这个条件看漏了) 好的这题贪心 每次选择没有被标记的最小点,然后把左下方和右上方都标记掉(记得标记重复时break,不然就挂了) 注意5000*5000的数组开两个int就是极限了 开多了妥妥MLE 所以T数组记得重复利用 暴力跑了38秒 不过这题每一行能够选择的区域一定是连续的 可以对于每一行维护一个l和r 每次更新取最值即可 这个代码跑了2

【BZOJ】【3671】【NOI2014】随机数生成器

贪心 嗯……其实生成这个矩阵就是一个$O(n^2)$的模拟 = = 然后?字典序最小?贪心呗= =能选1就选1,然后能选2就选2…… 我们发现,对于矩阵(1,1)~(n,m),假设1的位置是(x,y),那么我们选完1以后,可选的范围变成了:(1,1)~(x,y) & (x,y)~(n,m),也就是将一个矩阵拆成四块,我们可以在左上和右下两块中递归地进行选择…… 那么我们每次选完之后,新的可选的范围其实暴力O(n)维护就可以了,因为我们总共只选$O(n)$次,每次维护的复杂度是$O(n)$,总复杂

【矩阵乘】【NOI 2012】【cogs963】随机数生成器

963. [NOI2012] 随机数生成器 ★★ 输入文件:randoma.in 输出文件:randoma.out 简单对照 时间限制:1 s 内存限制:128 MB **[问题描写叙述] 栋栋近期迷上了随机算法,而随机数是生成随机算法的基础.栋栋准备使用线性同余法(Linear Congruential Method)来生成一个随机数列.这样的方法须要设置四个非负整数參数m,a,c,X[0],依照以下的公式生成出一系列随机数{Xn}: X[n+1]=(aX[n]+c) mod m 当中mod

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