目录

noip被吊打29

目录

真就 Ctrl + C Ctrl + V A题呗

T! 最长不下降子序列

这题无题解,因为它简单。但是矩阵快速幂的正解我也不会

把考场上的特判和dp复制粘贴过来再魔改一下就A了(大雾

Code
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <bits/stdc++.h>
#define For(i, l, r) for (long long i = (l), i##end = (r); i <= i##end; ++i)
#define Fordown(i, r, l) for (long long i = (r), i##end = (l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std;
const int maxn = 1000100;

template<typename type>
type read() {
  type s = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    s = s * 10 + ch - '0';
    ch = getchar();
  }
  return s * f;
}

long long n, ans;
long long len, prelen, t0, pre, a, b, c, d, ppre;
long long vis[233], num[maxn], dp[maxn], opt[maxn];
bool isCeq0;
int32_t main() {
  n = read<long long>();
  t0 = read<long long>();
  a = read<long long>();
  b = read<long long>();
  c = read<long long>();
  d = read<long long>();
  if (c == 0) {
    isCeq0 = 1;
  }
  if (t0 == 0 && c == 0) {
    cout << n << endl;
    return 0;
  }
  if (n > 1000000) {
    pre = t0;
    num[1] = t0;
    long long flg = 0;
    dp[1] = 1;
    For(i, 2, 10000) {
      dp[i] = 1;
      ppre = pre;
      pre = (a * pre * pre + b * pre + c) % d;
      if (vis[pre] && flg == 1) break;
      if (vis[pre]) {
	flg = 1;
      }
      vis[pre] = i;
      num[i] = pre;
      
    }
    long long ende = vis[ppre] - 1, lstn = ppre;
    For(i, 1, ende) {
      if (num[i] == lstn) {
	prelen = i - 1;
	len = ende - i + 1;
	break;
      }
    }
    long long tms = (n - 1ll * prelen) /  len;
    ende += len * 149;
    int len_max = 0;
    pre = t0;
    num[1] = t0;
    For(i, 2, ende) {
      num[i] = pre = (a * pre * pre + b * pre + c) % d;
    }
    int pos0 = 0;
    For(i, 1, ende) {
      if (!pos0 && num[i] == 0) pos0 = i;
      if (num[i] >= opt[len_max]) {
	opt[++len_max] = num[i];
	dp[i] = len_max;
      } else {
	int pos = lower_bound(opt + 1, opt + 1 + len_max, num[i]) - opt;
	opt[pos] = num[i];
	dp[i] = pos;
      }
    }
    int tmp = 0;
    for (long long i = prelen + 1; i <= n - len * tms; i++) {
     if (num[i] == opt[len_max]) tmp++;
   }
    if (isCeq0)
      cout << max(len_max * 1ll, n - pos0 + 1) << endl;
    else
      cout << len_max + tms - 150 + tmp<< endl;
    
  } else {
    int len_max = 0;
    pre = t0;
    num[1] = t0;
    For(i, 2, n) {
      num[i] = pre = (a * pre * pre + b * pre + c) % d;
    }
    int pos0 = 0;
    For(i, 1, n) {
      if (!pos0 && num[i] == 0) pos0 = i;
      if (num[i] >= opt[len_max]) {
	opt[++len_max] = num[i];
	dp[i] = len_max;
      } else {
	int pos = lower_bound(opt + 1, opt + 1 + len_max, num[i]) - opt;
	opt[pos] = num[i];
	dp[i] = pos;
      }
    }
    if (isCeq0)
      cout << max(len_max * 1ll, n - pos0 + 1) << endl;
    else
      cout << len_max << endl;
  }
  return 0;
}

/*
  10
  1 1 3 5 37
  1 9 2 15 16 13 28 22 0 5 8 19 16
*/

  </code>