LuoGuP3774:[CTSC2017]最長のシーケンスを増加

神魔法の奇美メイミュウミュウ。

次のセクションでは、私の質問上記羅区内の溶液から直接コピーされます。

溶液

ヤング図形は、(Aまたはしない)行うには良いでしょう。このトピックについて学ぶために来ます。\(ディルワース\)定理は、名前のように、非リットルの数がヤングを維持するために、行列の各行と、問い合わせを注文した後の状態の現在のサブシーケンスに解決することができ、これは、クエリの前にある\(k個の\ )の要素と行の数、そのフェンウィックツリーの統計情報。

しかし、空間が開口部より小さくなり、必要な非リットル系列長Lの数は、マトリックス中の二つの目的を有することができ、配列、配列を必要リットルの非リットルと同数の必要な長さに必要な配列と同じであることに注意代わり状(行列は、行の数は、サブシーケンス番号であると考えることができる、長さが最長のサブシーケンスのサブシーケンスで次の要件の最も異なります)。

それは、(エラーも表現を許してください場合、私は、線形代数を学んだことはありません)、二つの相互行列の転置の形状です。

想定される\は(SZ = \ SQRT N \ ) 次に、行数よりも大きい\(SZ \)を実証することができるの転置行列、横に必要とされるであろう\(X \ [1、 SZ] \) と縦\(のy \ [1、 SZ] \) 全ビット、およびこの範囲外のビットの両方の間で全ての可能な位置で、それが範囲内(ビットのすべてを想定し、転置されているのでマトリックス\(X \で[SZ + 1、n]は、Yの\ [SZ + 1、N] \) 領域)、数量を超える\(N- \)

次いで、マトリックス横軸転置\(X \で[SZ + 1、N] \) の範囲で、縦存在してはならない([SZ +のY \ \を \ nは、1]) 点。

2つ維持することができる\(SZの\回数N \)行列ソルバーを。

コード

#include<bits/stdc++.h>
using namespace std;
const int N = 50000 + 5, M = 233;
inline int lowbit (int u) {return u & (-u);}
int tree[N];
inline void add (int u, int v) {while (u <= N - 5) tree[u] += v, u += lowbit (u);}
inline int query (int u) {int res = 0; while (u) res += tree[u], u -= lowbit (u); return res;}
struct Q {int m, k, id, ans;}qq[N << 2];
int sz, n, b[N], q;
struct Matrix {
    int info[M][N], sign;
    inline void insert (int u, int v, int p) {
        if (u > sz) {return ;}
        int l = 1, r = min (v, info[u][0] + 1), mid;
        while (l < r) {
            mid = (l + r) / 2;
            if (sign ^ (info[u][mid] < p)) {r = mid;}
            else {l = mid + 1;}
        }
        swap (info[u][l], p);
        info[u][0] = max (info[u][0], l);
        if (p) {insert (u + 1, l, p);}
        else {
            if (sign) {if (l > sz)add (l, 1);}
            else {add (u, 1);}
        }
    }
}m1, m2;
int main () {
    m1.sign = 0, m2.sign = 1;
    scanf ("%d%d", &n, &q);sz = sqrt (n);
    for (int i = 1; i <= n; ++i) {scanf ("%d", &b[i]);}
    for (int i = 1; i <= q; ++i) {scanf ("%d%d", &qq[i].m, &qq[i].k);qq[i].id = i;}
    sort (qq + 1, qq + q + 1, [](Q a, Q b){return a.m < b.m;});
    int pre = 0;
    for (int i = 1; i <= q; ++i) {
        while (pre < qq[i].m) {
            ++pre;
            m1.insert (1, INT_MAX, b[pre]);
            m2.insert (1, INT_MAX, b[pre]);
        }
        qq[i].ans = query (qq[i].k);
    }
    sort (qq + 1, qq + q + 1, [](Q a, Q b){return a.id < b.id;});
    for (int i = 1; i <= q; ++i) {printf ("%d\n", qq[i].ans);}
    return 0;
}

結論

ヤング図形は非常に興味深いものでしたが、この質問には、このソリューションは、非常に興味深いああです。

おすすめ

転載: www.cnblogs.com/ChiTongZ/p/11221018.html