XOR @ 1577の数字を作る - 51nod @


@説明@

N 1からnまでの番号左から右に、添え字の総数。

(L-TH及びRの数を含む)への最初からRのL個のそれぞれが、それらのいくつかの数は、排他的またはKであるように選択されたかどうかのm回のクエリの合計

入力
整数nの最初の行の(0 <N <= 500,000 )。
n個の整数の第2行、0 <各数<2 ^ 30。
第三の行数m、問い合わせを示す番号(0 <M <=50万) 。
m行ごとに次の3行、L、R、K(0 <L <= R <= N、0 <K <2 ^ 30)。

出力
Mライン、各行動YESまたはNO

サンプル入力
5
1 2 4 6
3
1 2 1
2 4 8
3 5 7
サンプル出力
YES
NO
NO

@溶液@

これらの数字の中には、排他的論理和の数を選択し、K.としてすることができます 解決するために、線形ベースを使用して考えることは困難ではありません。

あなたは間隔構築タイトル与えられたデータの範囲を指示したい場合は、[L、R]は、リニアグループは実際には容易ではないです。
例えば、ラジカルとMoのチームは、確かにブロックを実行しません。オンラインセグメントツリーO(nlog ^ 3 n)を使って、パーティションは、O(nlog ^ 2のn)とオフラインでいくつかのポイントをすることができます行われますが、まだ十分ではないことができます。
キーは、私たちが[L、R]は直鎖状の基である構築したいということである二つのグループの線形操作をマージ関与し、操作の複雑さは常にnは倒れません^ 2ログインされています。

角度を変更したい場合があります。私たちは与えられたRとKは、Lは左または値以上に高いが、排他的であることが判明することができます。だから我々は"L、その後、Lを比較する初のXOR KがLとすることができる見つけることを試みることができます正当性の大きさを決定します。
私たちは、線形独立線形最も近い数のR形状のR基の複数のそれぞれについて、維持しよう。このアイデアは、問題解決のアイデアのbzoj3514に似ています。

具体的な操作は、我々は左から右へ掃引、リニアR -1-イル基Rは、直鎖状放出送達です。
ハイからローへの当社のリニアベース。i番目のビットの現在の数が1の場合、i番目のビットグループでリニアな外観は、すでにいくつかあります。より直線的であり、グループの数が現在の数がRに近いそのうちのいくつかは場合の数は、に直接行かない場合は、別の挿入操作が続行に線形のグループに近くなります。
バブルソートのようなビットは、数はR、いくつかの他のスクイーズアウトに近くなります。

同時に、我々はRの数に近いとして、上側のリニア・グループを見つけることができます
ですから、Lよりも少し小さいの位置の数に遭遇した場合、我々は、異なるまたはK試してみると、中央値は、我々が必要とKをXORするとき、「NO」であることが直接決定することができているとき。
トラブルの多くを証明するために、ここで厳密に真実を伝えるために。私はアルゴリズムが正しさのより簡潔な証拠を見つけることができない、能力を制限しました。
結局、ベースがリニア線形代数ああです。どのようにそれは非常に簡単です。

@acceptedコード@

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 500000;
int read() {
    int x = 0; char ch = getchar();
    while( ch > '9' || ch < '0' ) ch = getchar();
    while( '0' <= ch && ch <= '9' ) x = 10*x + ch - '0', ch = getchar();
    return x;
}
void insert(int *pos, int *b, int x, int p) {
    for(int i=29;i>=0;i--) {
        if( x & (1<<i) ) {
            if( b[i] == 0 ) {
                b[i] = x;
                pos[i] = p;
            }
            else if( pos[i] < p ) {
                swap(pos[i], p);
                swap(b[i], x);
            }
            x ^= b[i];
        }
    }
}
bool search(int *pos, int *b, int x, int p) {
    for(int i=29;i>=0;i--) {
        if( x & (1<<i) ) {
            if( b[i] == 0 || pos[i] < p )
                return false;
            x ^= b[i];
        }
    }
    return true;
}
int pos[MAXN + 5][30], b[MAXN + 5][30];
int main() {
    int n, m; n = read();
    for(int i=1;i<=n;i++) {
        int x = read();
        for(int j=29;j>=0;j--)
            pos[i][j] = pos[i-1][j], b[i][j] = b[i-1][j];
        insert(pos[i], b[i], x, i);
    }
    m = read();
    for(int i=1;i<=m;i++) {
        int L = read(), R = read(), K = read();
        puts(search(pos[R], b[R], K, L) ? "YES" : "NO");
    }
}

@詳細@

長い線形グループのいかなるレビューはありません。この質問を書き込む場合、偽のリニアベースを思い付きます。WAとても悲劇的。

当社グループは、動的方程式にガウスの消去に参加線形挿入類推することがあります。(その下のi番目のビットの最上位ビットでリニアベースのIビットのバイナリ数1と呼ばれる...それはやや複雑そうです)が、我々は、特殊なリニアベースの構築ので、これらの特性を満たすことができないガウスの消去法を記述する必要があるため。
さらに特殊線形群があれば、即ちリニアイル要件、(最も単純な形のガウスの消去法に類似)点をさらに得るいくつかのビットI、iビットバイナリディレクトリは、他の場所に0です。

多くの人がオフラインでやるようだが、この質問は、場所ごとに線形ベースのストレージからオンラインで行うことができます。

おすすめ

転載: www.cnblogs.com/Tiw-Air-OAO/p/11123375.html