タイトル説明
配列A1は、A2、...、サブセグメントは、それが連続的な部分、すなわち、Alであることを意味し、アル+ 1、...、 AR
容易に長さNのシーケンス$ \ FRAC {N(N +、見つけることが 1 )} {2} $
のサブセクション。例えば3,7,4シーケンス次のサブセクション:
(3)、(3,7)、(3,7,4)、(7)、(7,4)、(4)
MIA所望のサブセグメントを決定し、再び一緒にそれらをXOR、排他的論理和しました。しかしCierraが、これはあまりにもシンプルだと思うので、彼女はQの問い合わせをした、その都度与えられた区間[L、R]は、私はあなたが対応するサブインデックス範囲のセグメントを傍受することを願って、上記の質問に答えます。
具体的には、お問い合わせ[L、R]は、あなたがAL、AL + 1、...、すべてのサブセグメントとAR XORとXORに答える必要があります。
入力形式
最初の行は、2つのスペースで区切られた整数N、Qを含有する
第二のラインは、n個のスペースで区切られた整数A1、A2、...、含ま
q行の後、空間Lによって分離された2つの整数を含む各行を、R、Qはグループを尋ねるために、表現します
出力フォーマット
排他的論理和との排他的論理和の全てのサブセグメントのための整数部を備え、各クエリ出力ライン、および
サンプル入力
5 3
1 2 3 4 5
1 3
2 4
2 5
サンプル出力
2
6
0
データの制限
データの30%を、N、q≤500
データの60%を、N、q≤5000
データの100%、1≤n、q≤200000,0≤ai≤109、Lの各セットに、Rは1≤L≤R≤n満足しています
時間と空間の制約
1000msで、512メガバイト
プッシュ式のタイトル
私たちは、ここで使用(\ SUMの\)\(すなわち、)+(代わりに)排他的論理和のセクションを表します。
タイトル検索私たちにしてみましょう\(\ sum_ {L} = ^ {I} R&LT \ sum_ {J}を= Iは、R&LT ^ {} \ sum_ K = {I}} ^ {a_iをJ \)。
まず、接頭Yihuo前処理を見て、\(S [] \) 、次いでそれは\(\ sum_ {i = L } ^ {R} \ sum_ {J =} ^ {R} S_ {J} \) ^ \(S_ {I-1} \) 、見つかった\(S_ {I-1} \) と\(J \)を独立した、我々は提案がです
$
\ sum_ {i = L} ^ {R} S_ {I-1} \回$((R - I + 1)・1)^
(\ \ sum_ {J =} ^ {R} S_ {J} \ )
アレイは、プレフィックスおよびT []を実行するように設定されて再び我々 S []、式はさらににすることができる
$
\ sum_ {L} = ^ {I} R&LT S_ {I} 1- \タイムズ$((R&LT - +。1 I)&1)^
$ R&LT T_ {} $ ^ \(1-T_ {I} \)
そして、60点がありました。
私たちは、最初のSの半分と取られていないが取られ、私たちがやっていると、プレフィックス、後半、およそ(R-I + 1)パリティれることがわかった\(T \)プレフィックスを作成し、ライン上に。
while (m--)
{
l = read(); r = read(); ans = 0;
if ((r - l + 1) & 1)ans = t[r];
else ans = 0;
ans ^= (p[r - 1] ^ p[l - 2]);
if (!(r & 1))ans ^= ji[r - 1] ^ ji[max(l - 2, 0)];
else ans ^= ou[r - 1] ^ ou[max(l - 2, 0)];
printf("%d\n", ans);
}
それぞれが行うことができるように\(O(1)\)尋ねました。
最後に、私がいます醜いですコード
#include <iostream>
#include <cstdio>
using namespace std;
int n, m, l, r, ans;
const int N = 200010;
int a[N], s[N], t[N], p[N], ji[N], ou[N];
inline int read()
{
int res = 0; char ch = getchar(); bool XX = false;
for (; !isdigit(ch); ch = getchar())(ch == '-') && (XX = true);
for (; isdigit(ch); ch = getchar())res = (res << 3) + (res << 1) + (ch ^ 48);
return XX ? -res : res;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; ++i)a[i] = read();
for (int i = 1; i <= n; ++i)s[i] = a[i] ^ s[i - 1];
for (int i = 1; i <= n; ++i)t[i] = s[i] ^ t[i - 1];
for (int i = 1; i <= n; ++i)p[i] = t[i] ^ p[i - 1];
for (int i = 1; i <= n; ++i)
if (i & 1)ji[i] = ji[i - 1] ^ s[i];
else ji[i] = ji[i - 1];
for (int i = 1; i <= n; ++i)
if (!(i & 1))ou[i] = ou[i - 1] ^ s[i];
else ou[i] = ou[i - 1];
while (m--)
{
l = read(); r = read(); ans = 0;
if ((r - l + 1) & 1)ans = t[r];
else ans = 0;
ans ^= (p[r - 1] ^ p[l - 2]);
if (!(r & 1))ans ^= ji[r - 1] ^ ji[max(l - 2, 0)];
else ans ^= ou[r - 1] ^ ou[max(l - 2, 0)];
printf("%d\n", ans);
}
return 0;
}