# T1、Global warming

## $Sol$：

$[l, r]$$d$ 不比 给 $[l, n]$$d$ 优；
$[l, r]$$d$ 不比 给 $[1, r]$$d$ 优。

## $Source$：

#include <cstdio>
#include <cstring>
#include <algorithm>
int in() {
int x = 0; char c = getchar(); bool f = 0;
while (c < '0' || c > '9')
f |= c == '-', c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }
inline int max(int _, int __) { return _ > __ ? _ : __; }

const int N = 2e5 + 5, M = 2e9;
int n, x, a[N], res;
int f[N], len;
int pre[N], suf[N];

struct segment_tree {
int t[N * 71], c[N * 71][2], rt, tot;
inline void clear() {
tot = 0;
}
inline int new_node() {
++tot;
t[tot] = c[tot][0] = c[tot][1] = 0;
}
void modify(int pos, int k, int tl, int tr, int &p) {
if (p > tot)
p = 0;
if (!p)
p = new_node();
chk_max(t[p], k);
if (tl == tr)
return chk_max(t[p], k);
int mid = ((long long)tl + tr) >> 1;
if (mid >= pos)
modify(pos, k, tl, mid, c[p][0]);
else
modify(pos, k, mid + 1, tr, c[p][1]);
}
int query_max(int l, int r, int tl, int tr, int &p) {
if (p > tot)
p = 0;
if (!p)
return 0;
if (l <= tl && tr <= r)
return t[p];
int mid = ((long long)tl + tr) >> 1;
if (mid < l)
return query_max(l, r, mid + 1, tr, c[p][1]);
if (mid >= r)
return query_max(l, r, tl, mid, c[p][0]);
return max(query_max(l, r, tl, mid, c[p][0]),
query_max(l, r, mid + 1, tr, c[p][1]));
}
} T;

void work() {
f[len = pre[1] = 1] = a[1];
for (int i = 2, p; i <= n; ++i) {
p = std::lower_bound(f + 1, f + 1 + len, a[i]) - f;
if (p == len + 1) {
f[++len] = a[i];
} else {
f[p] = a[i];
}
pre[i] = p;
}

res = pre[n];
T.modify(a[n], 1, -M, M, T.rt);
len = suf[n] = 1, f[n] = a[n];
for (int i = n - 1, p; i; --i) {
p = std::upper_bound(f + n - len + 1, f + 1 + n, a[i]) - f - 1;
if (p == n - len) {
f[n - len] = a[i];
++len;
} else {
f[p] = a[i];
}
suf[i] = n - p + 1;
chk_max(res, pre[i] + T.query_max(a[i] - x + 1, M, -M, M, T.rt));
T.modify(a[i], suf[i], -M, M, T.rt);
}
}

int main() {
//freopen("in", "r", stdin);
freopen("glo.in", "r", stdin);
freopen("glo.out", "w", stdout);
n = in(), x = in();
for (int i = 1; i <= n; ++i)
a[i] = in();
work();
printf("%d\n", res);
return 0;
}


# T2、Mobitel

$Time \ Limits: 6000 ms$ $Memory \ Limits: 64 MB$

## $Sol$：

$\lfloor \frac{ \lfloor \frac{S}{x} \rfloor } {y} \rfloor = \lfloor \frac{S}{xy} \rfloor$，所以这样是对的。

$prf$
$i \leq \sqrt{N}$ 时，$\lfloor \frac{N}{i} \rfloor$ 不会超过 $\sqrt{N}$ 种；
$i > \sqrt{N}$ 时，$\lfloor \frac{N}{i} \rfloor < \sqrt{N}$，不会超过 $\sqrt{N}$ 种。
$Q.E.D.$

## $Source$：

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
int in() {
int x = 0; char c = getchar(); bool f = 0;
while (c < '0' || c > '9')
f |= c == '-', c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

const int N = 305, mod = 1e9 + 7;

int R, C, n, mp[N][N], f[2][N + N][2005];
int nn, num[2005], id[1000005];

inline void add(int &_, int __) {
_ += __, _ = _ < mod ? _ : _ - mod;
}

int qpow(int base, int b, int ret = 1) {
for (; b; b >>= 1, base = 1ll * base * base % mod)
if (b & 1)
ret = 1ll * ret * base % mod;
return ret;
}

int combination(const int n, const int m) {
if (n < m)
return 0;
int ret = 1;
for (int i = 2; i <= m; ++i)
ret = 1ll * ret * i % mod;
ret = qpow(ret, mod - 2);
for (int i = n - m + 1; i <= n; ++i)
ret = 1ll * ret * i % mod;
return ret;
}

int main() {
//freopen("in", "r", stdin);
freopen("mobitel.in", "r", stdin);
freopen("mobitel.out", "w", stdout);
R = in(), C = in(), n = in();
for (int i = 1; i <= R; ++i)
for (int j = 1; j <= C; ++j)
mp[i][j] = in();

for (int i = 1; i < n; i = (n - 1) / ((n - 1) / i) + 1) {
num[++nn] = (n - 1) / i;
id[(n - 1) / i] = nn;
}

int cur = 0;
f[1][1][id[(n - 1) / mp[1][1]]] = 1;
for (int i = 2; i <= R + C - 1; ++i, cur ^= 1) {
memset(f[cur], 0, sizeof(f[cur]));
for (int j = std::max(1, i - C + 1); j <= R && i + 1 - j; ++j) {
for (int k = 1; k <= nn; ++k) {
add(f[cur][j][id[num[k] / mp[j][i + 1 - j]]], f[cur ^ 1][j][k]);
add(f[cur][j][id[num[k] / mp[j][i + 1 - j]]], f[cur ^ 1][j - 1][k]);
}
}
}
cur ^= 1;
int res = 0;
for (int i = 1; i <= nn; ++i)
printf("%d\n", (combination(R + C - 2, C - 1) - res + mod) % mod);
return 0;
}


# T3、Lottery

$q \ (q \leq 100)$ 组询问，第 $j$ 组询问给出一个 $k_j \ (k_j \leq l)$，求每个子串与多少个其它的子串可称为 $k_j$ 相似。
$Memory \ Limits: 32MB$

## $Sol$：

$f_{i, j}$ 表示与第 $i$ 个子串 $j$ 相似的子串数量，空间复杂度 $O(n^2)$ ，显然不行；

## $Source$：

#include <cstdio>
#include <cstring>
#include <algorithm>
int in() {
int x = 0; char c = getchar(); bool f = 0;
while (c < '0' || c > '9')
f |= c == '-', c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return f ? -x : x;
}
template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }

const int N = 1e4 + 5;

struct query {
int id, k;
} b[105];
int n, L, q, a[N], id[N];
int mp[N][105], res[N];

inline bool cmp_id(const query &i, const query &j) {
return i.id < j.id;
}

inline bool cmp_k(const query &i, const query &j) {
return i.k < j.k;
}

void work() {
std::sort(b + 1, b + 1 + q, cmp_k);
for (int i = 1; i <= L; ++i)
id[i] = std::lower_bound(b + 1, b + 1 + q, (query){0, i}, cmp_k) - b;
for (int i = 1, now; i <= n - L; ++i) {
now = 0;
for (int j = 1; j <= L; ++j)
now += (a[j] != a[j + i]);
++mp[1][id[now]];
++mp[1 + i][id[now]];
for (int x = 2, y; x + i <= n - L + 1; ++x) {
y = x + i;
now -= (a[x - 1] != a[y - 1]);
now += (a[x + L - 1] != a[y + L - 1]);
++mp[x][id[now]];
++mp[y][id[now]];
}
}
for (int i = 1; i <= n - L + 1; ++i)
for (int j = 1; j <= q; ++j)
mp[i][j] += mp[i][j - 1];
std::sort(b + 1, b + 1 + q, cmp_id);
for (int i = 1; i <= q; ++i) {
for (int j = 1; j <= n - L + 1; ++j)
printf("%d ", mp[j][id[b[i].k]]);
puts("");
}
}

void input() {
n = in(), L = in();
for (int i = 1; i <= n; ++i)
a[i] = in();

q = in();
for (int i = 1; i <= q; ++i)
b[i] = (query){i, in()};
}

int main() {
//freopen("in", "r", stdin);
freopen("lottery.in", "r", stdin);
freopen("lottery.out", "w", stdout);
input();
work();
return 0;
}

posted @ 2019-08-20 20:45  15owzLy1  阅读(83)  评论(3编辑  收藏