zoukankan      html  css  js  c++  java
  • [NOI2014]随机数生成器

    嘟嘟嘟


    我就纳闷儿这题为啥是紫题,原来是因为卡内存……


    这题前面讲了半天的随机数怎么生成,我还以为要在这搞什么事情。然而你只要按题目(O(n * m + q))生成一个矩阵就没了。
    关于选路径,因为最后要排序,所以肯定是贪心的从小的开始选,能选就选,选到(n + m - 1)为止。
    选的时候判断这个数能否选必须是(O(1))的,(O(logn))的就过不了,但更新可以是(O(n))的。所以我们选了一个数,就维护每一行能选的数的的区间的左右端点,然后判断这个数能否选只要看这个数所在行的区间是否包含这个数所在列就好了。


    这题特别卡内存,最多只让开两个(n * m)的数组。所以最后存每一个数的坐标的时候,得编码成一个int,直接存两个int就gg了。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<assert.h>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 5e3 + 5;
    In ll read()
    {
      ll ans = 0;
      char ch = getchar(), last = ' ';
      while(!isdigit(ch)) last = ch, ch = getchar();
      while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
      if(last == '-') ans = -ans;
      return ans;
    }
    In void write(ll x)
    {
      if(x < 0) x = -x, putchar('-');
      if(x >= 10) write(x / 10);
      putchar(x % 10 + '0');
    }
    In void MYFILE()
    {
    #ifndef mrclr
      freopen("ho.in", "r", stdin);
      freopen("ho.out", "w", stdout);
    #endif
    }
    
    int n, m, Q;
    int x0, A, B, C, D;
    
    int a[maxn * maxn];
    In void init()
    {
      ll tp1 = x0, tp2;
      for(int i = 1; i <= n * m; ++i)
        {
          a[i] = i;
          tp2 = (1LL * A * tp1 % D * tp1 % D + 1LL * B * tp1 % D + C) % D;
          swap(a[i], a[tp2 % i + 1]);
          tp1 = tp2;
        }
    }
    
    int pos[maxn * maxn];
    int l[maxn], r[maxn];
    In void change(int x, int y)
    {
      for(int i = 1; i < x; ++i) r[i] = min(r[i], y);
      for(int i = x + 1; i <= n; ++i) l[i] = max(l[i], y);
    }
    
    int main()
    {
      //MYFILE();
      x0 = read(), A = read(), B = read(), C = read(), D = read();
      n = read(), m = read(), Q = read();
      init();
      for(int i = 1; i <= Q; ++i)
        {
          int x = read(), y = read();
          swap(a[x], a[y]);
        }
      for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j) pos[a[(i - 1) * m + j]] = i * 5001 + j;
      for(int i = 1; i <= n; ++i) l[i] = 1, r[i] = m;
      for(int i = 1, tot = 0; i <= n * m; ++i)
        {
          int x = pos[i] / 5001, y = pos[i] % 5001;
          if(y >= l[x] && y <= r[x])
    	{
    	  change(x, y);
    	  write(i), space;
    	  if(++tot == n + m - 1) break;
    	}
        }
      return 0;
    }
    
  • 相关阅读:
    BZOJ2243: [SDOI2011]染色
    BZOJ1036: [ZJOI2008]树的统计Count
    转自 x_x_的百度空间 搞ACM的你伤不起
    wcf test client
    wcf test client
    log4net编译后命名空间找不到的问题
    log4net编译后命名空间找不到的问题
    Hive Getting Started
    Hive Getting Started
    刚听完CSDN总裁蒋涛先生的学术报告
  • 原文地址:https://www.cnblogs.com/mrclr/p/10925170.html
Copyright © 2011-2022 走看看